7

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

asked Sep 1, 2013 at 8:07

1 Answer 1

7

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().

answered Sep 1, 2013 at 8:46
Sign up to request clarification or add additional context in comments.

2 Comments

Can a single socket client object send and receive data with server only once, or more? As in here:stackoverflow.com/questions/8627986/… You could comment over there to clarify
The short answer is that a single client object can send as much data as it wants and for as long as it wants. Once a client is done sending all the data it needs to send, it can then call close() to terminate the connection.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.