1
votes

I am trying to create a simple multiplayer mode for a little game using python. What I want to do is sharing the position of each player connected to the server. Right now though I am stuck struggling with having even one client communicating with the server, using the socket module and json files (which don't seem to cause problems though).

The error I get and when:

As soon as I try to send something via client a second time I get the " [Errno 32] Broken pipe" error. According to some googling this happens when the connection is closed. Unfortunately I don't see where it is getting closed.

Currently my code is pretty much this: http://thomasfischer.biz/python-simple-json-tcp-server-and-client/ . I didn't change much since I immediately ran into this problem.

Server Client:

import SocketServer
import json

class MyTCPServer(SocketServer.ThreadingTCPServer):
    allow_reuse_address = True

class MyTCPServerHandler(SocketServer.StreamRequestHandler):
    def handle(self):
        try:
            data = json.loads(self.request.recv(1024).strip())
            print data
        except Exception, e:
            print "Exception wile receiving message: ", e

server = MyTCPServer(('127.0.0.1', 13373), MyTCPServerHandler)
server.serve_forever()

Player Client:

import SocketServer
import json

def __init__(self):
    self.S = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    self.S.connect(('127.0.0.1', 13373))

*lots of game related code*

pos = {'id':id, 'pos': (x, y, z)}
self.S.send(json.dumps(pos))
self.position = (x, y, z)

if __name__ == '__main__':
    main() #to keep the game running and updating

Error:

  File "/usr/local/lib/python2.7/dist-packages/pyglet/app/__init__.py", line 123, in run
    event_loop.run()
  File "/usr/local/lib/python2.7/dist-packages/pyglet/app/base.py", line 135, in run
    self._run_estimated()
  File "/usr/local/lib/python2.7/dist-packages/pyglet/app/base.py", line 164, in _run_estimated
    timeout = self.idle()
  File "/usr/local/lib/python2.7/dist-packages/pyglet/app/base.py", line 273, in idle
    redraw_all = self.clock.call_scheduled_functions(dt)
  File "/usr/local/lib/python2.7/dist-packages/pyglet/clock.py", line 309, in call_scheduled_functions
    item.func(ts - item.last_ts, *item.args, **item.kwargs)
  File "/home/tim/tools/Pyglet/PlayerClient.py", line 609, in update
    self._update(dt / m)
  File "/home/tim/tools/Pyglet/PlayerClient.py", line 641, in _update
    self.S.send(json.dumps(pos))
socket.error: [Errno 32] Broken pipe
1

1 Answers

3
votes

Broken Pipe occurs when one end of the connection tries sending data while the other end has already closed the connection.

 self.S.send(json.dumps(pos)) 

When the above is being attempted the server has already closed the connection. Possibly during the *lots of game related code* And client side TCP is aware of that.But the client application is not. Check the tcpdump b/w the client and server. You should be seeing FIN or RST from the server.

You need to have mechanism to capture TCP events like FIN/RST in your application code. TCP applications should not be written with out the mechanisms to capture asynchronous TCP events.