我想在python中构建一个客户端/服务器应用程序,其中:
我试图制作一个示例代码来模拟这种行为,但问题是,当服务器尝试接收包时,它会收到自上次调用“recv”以来发送的所有数据。
问题是:有没有办法只接收最后一个包,即忽略之前发送的内容?
这是我使用流套接字的示例代码(我也尝试过UDP,相同的行为)
服务器端:
import socket
import multiprocessing
import testClient
import time
address = ('localhost', 50000)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(address)
#Start the client
client = multiprocessing.Process(target=testClient.testClient)
client.start()
s.listen(1)
conn, addr = s.accept()
print 'Received connection {}, {}'.format(conn, addr)
print 'Server> receiving data'
data = conn.recv(15)
print 'Server> received data',repr(data)
time.sleep(10)
print 'Server> receiving data'
data = conn.recv(15)
print 'Server> received data',repr(data)
客户方:
import socket
import time
import numpy
serverAddress = ('localhost', 50000)
def testClient():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 50000))
count = 0
while True:
data = 'Test string %d'%count
print '>client: sending data',data
s.sendall(data)
time.sleep(1)
count +=1
s.close()
示例输出:
>client: sending data Test string 0
Server> receiving data
Server> received data 'Test string 0'
>client: sending data Test string 1
>client: sending data Test string 2
>client: sending data Test string 3
>client: sending data Test string 4
>client: sending data Test string 5
>client: sending data Test string 6
>client: sending data Test string 7
>client: sending data Test string 8
>client: sending data Test string 9
Server> receiving data
Server> received data 'Test string 1Te'
...
我想第二次收到的是“测试字符串9”。有办法做到这一点还是完全不现实?
修改
根据迈克的回答,我意识到当我需要阅读更多数据时,我可能需要关闭连接并打开一个新连接。该解决方案可以使用数据报套接字来实现。这是我的工作示例:
服务器端
import socket
import multiprocessing
import testClientUDP
import time
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_address = ('localhost', 10000)
print 'Server> starting up on %s port %s' % server_address
sock.bind(server_address)
#Start client process
client = multiprocessing.Process(target = testClientUDP.testClient)
client.start()
data, address = sock.recvfrom(4096)
print 'Server> received data: ',data
#Close socket
sock.close()
time.sleep(5)
#Open a new socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(server_address)
data, address = sock.recvfrom(4096)
print 'Server> received data: ',data
sock.close()
time.sleep(5)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(server_address)
data, address = sock.recvfrom(4096)
print 'Server> received data: ',data
sock.close()
客户端
import socket
import time
def testClient():
# Create a UDP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_address = ('localhost', 10000)
try:
count = 0
while True:
# Send data
data = 'Test message %d'%count
print 'Client> sending "%s"' %data
sent = sock.sendto(data, server_address)
time.sleep(1)
count += 1
finally:
print 'Client> closing socket'
sock.close()
输出
Server> starting up on localhost port 10000
Client> sending "Test message 0"
Server> received data: Test message 0
Client> sending "Test message 1"
Client> sending "Test message 2"
Client> sending "Test message 3"
Client> sending "Test message 4"
Client> sending "Test message 5"
Server> received data: Test message 5
Client> sending "Test message 6"
Client> sending "Test message 7"
Client> sending "Test message 8"
Client> sending "Test message 9"
Client> sending "Test message 10"
Server> received data: Test message 10
Client> sending "Test message 11"
Client> sending "Test message 12"
...
答案 0 :(得分:0)
睡觉,等待“所需”的消息将无法正常工作,因为它仍然是相同的连接,并且流上有数据堆积起来。
选项1:
一种方法是在while循环中调用conn.recv(1024)
(您可以使用任何其他值,1024适用于大多数情况),直到流为“空”并丢弃您所在的8个消息块不感兴趣(使用计数器变量)。
选项2:
如果您确切地知道堆积了多少比特,您也可以使用conn.recv(13)
接收您的第一条消息,然后休眠,然后拨打conn.recv(13*8)
(读取您的13位消息的8倍 - 这是数据1-9,你不想要的),下次你从流中读取它时,它将包含你的第9条消息。
然而,这在很大程度上依赖于知道客户端将发送多少位,因此第一个选项会更好。