TCP插座即使在执行sendall()后也无法发送数据

TCP Socket unable to send data even after executing sendall ()

本文关键字:数据 插座 sendall 执行 TCP      更新时间:2023-10-16

嗨,我有多个系统通过TCP连接通过消息进行通信。

在两者之间的通信过程中,我首先将消息发送为"开始过程",作为回报,它应该回复为"过程启动"

但是,在没有任何例外执行行sendall("过程启动")时未收到消息"过程启动"。

我的示例代码如下:

TCP初始化:

def __init__(self):
    self.tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    self.tcp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    self.tcp.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, struct.pack('ll',0,1))
    self.tcp.bind('',12000)
    self.tcp.listen(1)
    self.client, seld.address = self.tcp.accept()
    (self.Ip,self.port)= self.address

主要funciton:

while True:
    msg =""
    try:
       msg = self.client.recv(512)
    except socket.error as e:
       if e[0] == 11:
           # exception for RECVTIMEO used in the socket creation.
           pass
    if (msg == "Start Process"):
          send = "Process Started"
          self.client.sendall(send)
          print "status sent"

执行此代码时,我能够接收消息"开始过程"。但是"过程启动"并未在执行行self.client.sendall(发送)时发送,我在Wireshark中捕获了数据包,我得到了包含"启动过程"的数据包,但是没有获得"启动过程"的数据包

有人可以帮我吗?

您的代码有多个问题,但是您现在正在努力的问题是,如果您使用telnet连接到端口12000并发送"启动过程"并点击Enter,则实际上将发送和接收启动过程 n而不是启动过程,而您的if语句则不匹配。如果您剥离了尾随的新线,则可以减轻以下方法:

try: 
    msg = self.client.recv(512)
    msg = msg.strip()

不过,您的程序可能需要进行一些调整。当您设置套接字非阻滞时,self.tcp.accept()会引起异常,因为您尝试接受尚未存在的连接。收到正确的消息后,self.client.recv()也是如此。当您添加条纹时,您的if子句将匹配,您将获得响应。但是,它只会继续做出响应,因为它立即尝试再次进行RECV(512),但在异常情况下失败,然后您抓住它并再次执行IF子句。MSG仍然是"启动过程",因为它没有更改(连续的RECV刚刚失败,没有返回"或无)。

尝试将您的if子句移入您的尝试/构造除外,并且仅在您实际收到的子句中比较味精。

这个程序也将非常浪费,因为它大多数时候都会在繁忙的循环中运行,等待连接或消息。如果您需要使用非阻滞插座,则需要解决此问题。

更好的方法可能是使用线程具有倾听并接受新连接的阻止线程,并且对于每个连接,它都会产生一个工作线程。然后,这些线程可以在RECV()中阻塞,直到收到消息为止。

只是一个想法。

hannu