我正在尝试在主机上发送TCP / IP上的消息。这是有效的,但由于某种原因,只需要为客户端的每个新消息重新实例化套接字。例如,这是一个发送三个单独消息的基本客户端:
import socket
host = '127.0.0.1'
class Client:
def __init__(self):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def connect(self):
self.sock.connect((host,12347))
def send(self,message):
self.sock.sendall(message)
def close(self):
self.sock.close()
if __name__ == "__main__":
message1 = "I am message 1"
message2 = "I am message 2"
message3 = "I am message 3"
#exp = Client()
#exp.connect()
for i in range(0,3):
try:
exp = Client()
exp.connect()
if i == 0:
txt = message1
elif i == 1:
txt = message2
elif i == 2:
txt = message3
exp.send(txt)
exp.close()
print i
exp.send(txt)
except:
pass
和接收的服务器:
#!/usr/bin/env python
import socket
class communication:
def __init__(self):
try:
host = '127.0.0.1'
self.Server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.Server.bind((host,12347))
self.Server.listen(1)
finally:
print "setup finished"
def recieve(self):
(connection, client_address) = self.Server.accept()
data = connection.recv(128)
return data
def close(self):
self.server.close()
if __name__ == "__main__":
exp = communication()
while True:
try:
(connection,client_address) = exp.Server.accept()
message = connection.recv(128)
finally:
print message
if message == "I am message 3":
exp.close()
您将看到我如何在for循环的每次迭代中重新调用Client类。这似乎是发送消息2和3所必需的。如果套接字在主代码的开头只与connect()函数一起实例化一次,那么服务器在第一条消息发送后挂起在recv()上。
我无法理解为什么会这样,并且套接字只需要在服务器端设置一次。我做错了什么,或者这是正常的吗?
谢谢!
答案 0 :(得分:0)
这比你想象的还要糟糕。看看你的服务器代码。 exp.Server.accept()
接受来自客户端的连接,但connection.receive()
完全忽略该连接并执行第二次self.Server.accept()
。你忽略了一半的关系!
接下来,您的服务器只进行一次接收....即使您尝试在连接上发送更多消息,服务器也会忽略它们。
但你不能只添加一个recv循环。您的客户端和服务器需要某种方式来标记消息边界,以便服务器知道如何将它们拉出来。一些基于文本的系统使用新行。其他人发送服务器可以读取的消息大小或固定大小的头。例如,HTTP使用新行和数据计数的组合。
如果你想从头开始学习插座,只要知道它们很复杂,你就需要学习。有很多方法可以构建服务器,您需要了解权衡。否则,从XMLRPC到zeromq有很多框架可以为你做一些繁重的工作。