gpt4 book ai didi

python - 网络编程问题

转载 作者:行者123 更新时间:2023-11-28 23:06:40 25 4
gpt4 key购买 nike

我写了一个客户端服务器程序,其中服务器向客户端发送程序,客户端执行接收到的程序。在这种情况下,它是 OpenGL 中的画线程序。问题是,在运行服务器和客户端时,整个程序,即将程序发送到服务器和客户端执行有时会发生,但有时执行不会发生。客户端连接,然后卡住。该程序也没有停止。在我的 friend 系统中也是如此,但在我的系统中它只在某些时候有效(大多数时候它不会)。可能是什么原因?我错过了什么吗?

我的服务器代码:

from OpenGL.GLUT import *
from OpenGL.GLU import *
from OpenGL.GL import *
import sys
import threading
import os
import socket

class ClientThread ( threading.Thread ):
# Override Thread's __init__ method to accept the parameters needed:
def __init__ ( self, channel, details ):
self.channel = channel
self.details = details
threading.Thread.__init__ ( self )

#Codes to be executed when thread is executed:
def run ( self ):
a1=self.channel.recv(1024)
print "client says:"+a1
print 'Received connection:', self.details [ 0 ]
finp = open("stringcheck.py","r")
#self.channel.send("#start\n")
info = finp.readlines()
for record in info:
self.channel.send(record)
#self.channel.send(info)
self.channel.send("#p")


server = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
server.bind ( ( '127.0.0.1', 4500) )
#Listens for connections made to socket.
#Specifies maximum number of queued connection.
server.listen ( 5 )
while True:
channel, details = server.accept()
#Create an instance of thread class and call its start method.
ClientThread ( channel, details ).start()

我的客户代码:
from OpenGL.GLUT import *
from OpenGL.GLU import *
from OpenGL.GL import *
OpenGL.ERROR_CHECKING=False
import os
import socket
import threading
import thread
import subprocess

class ConnectionThread( threading.Thread ):

def run ( self ):

client = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
client.connect( ( '127.0.0.1', 9000) )
client.send("connected")
a=client.recv(1024)
b=a
f=1
while f:
print 'sdf'
a = client.recv(1024)
print 'qwe'
if a=="#p":
f=0
break
b+=a
print b
exec(b)

client.close()
ConnectionThread().start()
from OpenGL.GLUT import *
from OpenGL.GLU import *
from OpenGL.GL import *
OpenGL.ERROR_CHECKING=False
import os
import socket
import threading
import thread
import subprocess

class ConnectionThread( threading.Thread ):

def run ( self ):

client = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
client.connect( ( '127.0.0.1', 9000) )
client.send("connected")
a=client.recv(1024)
b=a
f=1
while f:

a = client.recv(1024)
print 'qwe'
if a=="#p":
f=0
break
b+=a
print b
exec(b)

client.close()
ConnectionThread().start()

最佳答案

1.一个TCP套接字是一个流 (数据包是一个实现细节)

网络堆栈进行了优化,以限制发送的数据包数量。因此,当您调用 send()在一个套接字上多次,网络堆栈可以在多个数据包之间自由拆分(或不拆分)数据。

在运行在真实网络上的计算机上,这比环回连接慢得多,如果您在调用 send() 时仍有数据包等待发送,然后将新数据附加到等待数据包中。在接收端,网络堆栈可以自由地合并多个数据包(从套接字接收的数据被缓冲)以立即向您呈现数据。

所以,在服务器中,你写:

for record in info:
self.channel.send(record)
self.channel.send("#p")

最后一个数据包可能包含程序的结尾和终止符,它们连接在一起。
在客户端:
a = client.recv(1024)
if a=="#p":
break

终止符可能不在接收数据包的开头,也可能不是数据包中存在的唯一字符。如果是这种情况,那么你没有检测到终止符,不要退出循环,调用 recv()又一次,从 recv() 起就停在这里是一个阻塞调用,服务器将不再发送任何数据。

因此,您必须选择另一种方式来了解服务器何时完成发送数据。有很多可能性:
  • 第一个明显的方法是在客户端,而不是 if a=="#p": ,写if a.endswith("#p"): .这更正了代码中存在的问题
  • 您也可以选择先发送节目的长度再发送。客户端读取长度,然后读取该字符数并停止
  • 服务器可以在发送完程序后简单地关闭连接。在客户端中,您检测到连接在 recv() 时关闭返回一个空字符串,你就知道程序被接收了。不幸的是,如果服务器在发送整个程序之前崩溃,您将在客户端执行一个不完整的程序

  • 有无数其他的可能性来纠正这个问题......

    2.你的接收逻辑不对

    现在,仔细看看接收逻辑(编辑代码以删除不相关的行):
    1. a=client.recv(1024)
    2. b=a
    3. f=1
    4. while f:
    5. a = client.recv(1024)
    6. if a=="#p":
    7. f=0
    8. break
    9. b+=a

    在这里,您首先等待一些数据(第 1 行)。然后你进入你的 while 循环(第 4 行),然后再次等待一些数据(第 5 行)!
    recv()是一个阻塞调用:这意味着它不会返回,直到有一些数据要返回或连接关闭。如果服务器发送的包括终止符在内的字节数少于 1024,您会在第 1 行收到所有内容(包括终止符),但仍然在第 5 行等待更多数据...

    请注意,您的测试中仍然存在一个错误:如果分隔符在 2 recv() 之间分割调用(如果程序正好是 1023 字节长,就会发生这种情况), a.endswith('#p')永远不会评估为 True .

    所以这是一个正确的接收逻辑,它会在收到一些数据后立即测试终止符:
    a = client.recv(1024)    
    b = a
    f = 1
    while f:
    if b.endswith("#p"):
    f=0
    break
    a = client.recv(1024)
    b += a

    请注意,这可以通过删除不必要的变量来大大简化:
    b = client.recv(1024)
    while not b.endswith("#p"):
    b += client.recv(1024)

    3.正确释放代码中使用的资源

    我一开始并没有强调这一点,但您应该始终正确关闭您的连接!

    使用python语言,一旦不再引用持有它的变量(在你的情况下,当它超出范围时),连接就会被隐式关闭。但是,明确地关闭它会清楚地表明您希望连接在什么时候关闭。

    某些实现可能会决定将资源的释放推迟到以后(Jython 用户可能遇到过这个问题),让连接保持打开状态......这没问题,但是当您的程序增长到以后可能会导致奇怪的行为功能更齐全的产品。

    关于python - 网络编程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4690155/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com