当前位置: 动力学知识库 > 问答 > 编程问答 >

Python, why it is errors 10035 (on server) and 10053 (on client) during using TCP sockets?

问题描述:

Almost 2 days I still have the same problem -client and server 'talks' to each other but I don't know why suddenly problem occurs during the communication. I tried really many things and unfortunately still the same problem.

I'm using python 2.7.5 on Windows 7.

My code:

cs_common.py

import socket

import os

import sys

import errno

from time import sleep

HOST = 'localhost'

MY_IP = socket.gethostbyname(socket.gethostname())

PORT = 50007

timeout_in_seconds = 2

def createSocket4server(host, port):

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.bind((host, port))

s.listen(4)

return s

def createSocket4Client(host, port, timeout_in_seconds=3):

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.connect( (host, port) )

print 'connected to %s port %s' % (host, port)

return s

sent = 0

def sendToSocket(socket_, data): # to debug

global sent

print sent, ') Sending:', data

socket_.send(data)

sent += 1

received = 0

def recvFromSocket(socket_):

global received

print '>>>>>>>>>>Trying to receive'

data = socket_.recv(1024)

print received, ') Received:', data

received += 1

return data

def sendDataToAllPlayers(data_to_send, connections):

for c in connections:

sendToSocket(c[0], data_to_send)

def trySendingAsLongAsNotSent(socket_, data):

while True:

try:

sendToSocket(socket_, data)

break

except socket.timeout:

pass

def tryReceivingAsLongAsNotReceived(socket_):

while True:

try:

data = recvFromSocket(socket_)

return data

except socket.timeout:

pass

server.py:

from cs_common import *

server = createSocket4server(HOST, PORT)

server.setblocking(0) # 1 switch off blocking

server.settimeout(timeout_in_seconds)

connections = []

counter = 0

while counter<3:

counter += 1

try:

c, addr = server.accept()

print 'Got connection from', addr

connections.append( [c, addr] )

except socket.timeout:

pass

if len(connections) == 0:

print 'No connections!'

exit()

number_of_players = len(connections)

print 'Connected with', number_of_players, 'players:'

print [ addr[1] for addr in connections ]

counter = 0

for c in connections:

counter += 1

number_of_the_player = counter

initial_game_data = str(number_of_the_player) + ' rest of initial game data'

sendToSocket(c[0], initial_game_data) # 2 sending initial game settings

sleep(1)

server.setblocking(1) # 3 switch on blocking

# MAIN LOOP #

while True:

print 'LOOP___________________________'

sendDataToAllPlayers('Synchronization data to players', connections) # 4 sending synchronization data to clients

# doing some stuff

for c in connections:

print 'received from player:', recvFromSocket(c[0]) # 5 receiving synchronization data from clients

client.py:

from cs_common import *

server = createSocket4Client(HOST, PORT)

server.setblocking(0) # 1 switch off blocking

server.settimeout(timeout_in_seconds)

initial_game_data = tryReceivingAsLongAsNotReceived(server) # 2 getting initial game settings

print 'received initial_game_data from server:', initial_game_data

sleep(1)

server.setblocking(1) # 3 switch on blocking

# MAIN LOOP #

while True:

print 'LOOP___________________________'

sunchronizing_data = recvFromSocket(server) # 4 receive synchronization data from server

print 'Received from server:', sunchronizing_data

# doing some stuff

sendToSocket(server, 'I was doing nothing during the frame')

When I run the codes above:

Output from client:

connected to localhost port 50007

>>>>>>>>>>Trying to receive

>>>>>>>>>>Trying to receive

>>>>>>>>>>Trying to receive

0 ) Received: 1 rest of initial game data

received initial_game_data from server: 1 rest of initial game data

LOOP___________________________

>>>>>>>>>>Trying to receive

1 ) Received: Synchronization data to players

Received from server: Synchronization data to players

0 ) Sending: I was doing nothing during the frame

LOOP___________________________

>>>>>>>>>>Trying to receive

Traceback (most recent call last):

File ".\client.py", line 19, in <module>

sunchronizing_data = recvFromSocket(server) # 4 receive synchronization data from server

File "...\pygame_my\cs_common.py", line 38, in recvFromSocket

data = socket_.recv(1024)

socket.error: [Errno 10053] An established connection was aborted by the softwar

e in your host machine

Output from server:

Got connection from ('127.0.0.1', 55768)

Connected with 1 players:

[('127.0.0.1', 55768)]

0 ) Sending: 1 rest of initial game data

LOOP___________________________

1 ) Sending: Synchronization data to players

received from player: >>>>>>>>>>Trying to receive

Traceback (most recent call last):

File ".\server.py", line 49, in <module>

print 'received from player:', recvFromSocket(c[0]) # 5 receiving synchronization data from clients

File "...\pygame_my\cs_common.py", line 38, in recvFromSocket

data = socket_.recv(1024)

socket.error: [Errno 10035] A non-blocking socket operation could not be completed immediately

I tried also the scripts on an another computer -the same problems. I tried also to deactivate not-blocking sockets -still problems

网友答案:

You need to make the child socket blocking. Add this call "c.setblocking(1)" in the server file (server.py) before you append the new connection using "connections.append( [c, addr] )" -- like the following snippet. Looks like the child socket is inheriting the non-blocking option from the parent server socket. With this change, I was able to run your code without any errors.

    c, addr = server.accept()
    print 'Got connection from', addr
    c.setblocking(1) # Make it blocking.
    connections.append( [c, addr] )

The other alternative would be to catch socket.error in the recvFromSocket() function in the cs_common.py -- this is because if the recv() timeouts becuase child sockets are non-blocking, then the recv() call will return with an error. Since your code is not handling it, your application runs into a problem.

And a generic note: If there are clients that would join after the initial list of 3 cliens, then I would recommend using a separate thread to handle incoming connections or to use a select() call to accept read-events for the server fd -- a read event on the server fd means that there is a pending connection and we should call an accept().

分享给朋友:
您可能感兴趣的文章:
随机阅读: