我试图在主机上发送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()上 .
我无法理解为什么会发生这种情况,并且套接字只需要在服务器端设置一次 . 我做错了什么,或者这是正常的吗?
谢谢!
1 回答
它比你想象的还要糟糕 . 看看你的服务器代码 .
exp.Server.accept()
接受来自客户端的连接,但connection.receive()
完全忽略该连接并执行第二次self.Server.accept()
. 你忽略了一半的联系!接下来,您的服务器只进行一次接收....即使您尝试在连接上发送更多消息,服务器也会忽略它们 .
但你不能只添加一个recv循环 . 您的客户端和服务器需要某种方式来标记消息边界,以便服务器知道如何将它们拉出来 . 一些基于文本的系统使用新行 . 其他人发送服务器可以读取的消息大小或固定大小的头 . 例如,HTTP使用新行和数据计数的组合 .
如果你想从头开始学习插座,只要知道它们很复杂,你就需要学习 . 有很多方法可以构建服务器,您需要了解权衡 . 否则,从XMLRPC到zeromq的许多框架都会为您做一些繁重的工作 .