Reputation: 187
I'm a newbie in network programming, so please forgive me if this is a dumb question :) I created 1 client and 1 SocketServer.ThreadingMixIn server on Ubuntu 10.04.2 using Python2.7, but it seems like I can only call sock.send() once in client, then I'll get a:
Traceback (most recent call last):
File "testClient1.py", line 33, in <module>
sock.send('c1:{0}'.format(n))
socket.error: [Errno 32] Broken pipe
Here's the code I wrote:
testClient1.py:
#! /usr/bin/python2.7
# -*- coding: UTF-8 -*-
import sys,socket,time,threading
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
sock.connect(('localhost',20000))
except socket.error:
print('connection error')
sys.exit(0)
n=0
while n<=1000:
sock.send('c1:{0}'.format(n))
result=sock.recv(1024)
print(result)
n+=1
time.sleep(1)
testServer.py:
#! /usr/bin/python2.7
# -*- coding: UTF-8 -*-
import threading,SocketServer,time
class requestHandler(SocketServer.StreamRequestHandler):
#currentUserLogin={} #{clientArr:accountName}
def handle(self):
requestForUpdate=self.rfile.read(4)
print(requestForUpdate)
self.wfile.write('server reply:{0}'.format(requestForUpdate))
class broadcastServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
pass
if __name__ == '__main__':
server=broadcastServer(('localhost',20000),requestHandler)
t = threading.Thread(target=server.serve_forever)
t.daemon=True
t.start()
print('server start')
n=0
while n<=60:
print(n)
n+=1
time.sleep(1)
server.socket.close()
I ran them in 2 separate terminals:
output of 1st terminal:
$ python2.7 testServer.py
server start
0
1
2
3
4
c1:0
5
6
7
8
9
10
11
...
output of 2nd terminal:
$ python2.7 testClient1.py
server reply:c1:0
Traceback (most recent call last):
File "testClient1.py", line 33, in <module>
sock.send('c1:{0}'.format(n))
socket.error: [Errno 32] Broken pipe
I tried calling sock.send() twice directly in testClient.py, for ex:
while n<=1000:
sock.send('c1:{0}'.format(n))
sock.send('12333')
result=sock.recv(1024)
print(result)
n+=1
time.sleep(1)
but the outputs of the terminals are still the same :( Can anyone please point out what am I doing wrong here? Thx in adv!
Here's the [Sol] I came up with. Thank you Mark:)
testClient1.py:
import sys,socket,time
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
sock.connect(('localhost',20000))
except socket.error:
print('connection error')
sys.exit(0)
n=0
while n<=10: #connect once
sock.send('c1:{0}'.format(n))
result=sock.recv(1024)
print(result)
n+=1
time.sleep(1)
sock.close()
#once you close a socket, you'll need to initialize it again to another socket obj if you want to retransmit
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
sock.connect(('localhost',20000))
except socket.error:
print('connection error')
sys.exit(0)
n=0
while n<=10: #connect once
sock.send('c3:{0}'.format(n))
result=sock.recv(1024)
print(result)
n+=1
time.sleep(1)
sock.close()
testServer.py:
import threading,SocketServer,time
class requestHandler(SocketServer.StreamRequestHandler):
#currentUserLogin={} #{clientArr:accountName}
def handle(self):
requestForUpdate=self.request.recv(1024)
print(self.client_address)
while requestForUpdate!='':
print(requestForUpdate)
self.wfile.write('server reply:{0}'.format(requestForUpdate))
requestForUpdate=self.request.recv(1024)
print('client disconnect')
class broadcastServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
pass
if __name__ == '__main__':
server=broadcastServer(('localhost',20000),requestHandler)
t = threading.Thread(target=server.serve_forever)
t.daemon=True
t.start()
print('server start')
n=0
while n<=60:
print(n)
n+=1
time.sleep(1)
server.socket.close()
Upvotes: 12
Views: 27385
Reputation: 177481
handle() is called in the SocketServer.StreamRequestHandler
once for each connection. If you return from handle
the connection is closed.
If you want the server to handle more than one send/recv, you must loop until recv() returns 0, indicating the client closed the connection (or at least called shutdown() on sends).
Also note that TCP is a streaming protocol. You'll need to design a message protocol that indicates the length or end of a message, and buffer recv
until you have a complete message. Check send
return value to make sure all the message is sent as well, or use sendall
.
Upvotes: 17