python中的套接字编程
我在套接字编程方面遇到了很多问题 随附代码如下(所有部分均取自本手册并一起编写) 我正在尝试将鼠标数据发送到客户端,但收到错误:python中的套接字编程,python,sockets,Python,Sockets,我在套接字编程方面遇到了很多问题 随附代码如下(所有部分均取自本手册并一起编写) 我正在尝试将鼠标数据发送到客户端,但收到错误: Traceback (most recent call last): File "srvr.py", line 29, in <module> serv.sendall(status) File "/usr/lib/python2.7/socket.py", line 224, in meth return getattr(self
Traceback (most recent call last):
File "srvr.py", line 29, in <module>
serv.sendall(status)
File "/usr/lib/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
TypeError: must be string or buffer, not int
您需要将要发送的数据类型转换为
字符串
或缓冲区
。错误信息非常清楚。您需要改为执行conn.send(str(status))
。您不需要“连续”更改数据,只需对str
对象更改一次。如果您使用自己的类,要控制此str
对象中的内容,您可以定义一个\uuuu str\uuu
方法。通过网络传输数据时,通常按照大端字节顺序进行打包。尽管一次只有三个单独的字节,因此字节顺序无关紧要,但我还是更喜欢打包和解包,因为这是一种常见的通信方式。此外,在接收网络数据时,通常要做的一件事是检查您是否实际收到了预期的数据量,否则您必须请求更多数据。为简单起见,请考虑以下功能:
def recv(sock, size):
data = ''
to_receive = size
while to_receive > 0:
data += sock.recv(to_receive)
to_receive = size - len(data)
return data
现在,代码中缺少的是一个通用协议。客户端充当原始无意义数据的接收器。相反,它应该充当三胞胎的接受者。除此之外,我建议让客户询问他想要多少个三胞胎。考虑到这一点,我将如何将您的客户端代码更改为:
import sys
import socket
import struct
serv_host = ''
serv_port = 29876
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((serv_host, serv_port))
# Tell the server how many triplets I want.
amount = int(sys.argv[1])
s.sendall(struct.pack('!i', amount))
pack_size = struct.calcsize('!bbb')
while amount:
status, dx, dy = struct.unpack('!bbb', recv(s, pack_size))
print status, dx, dy
amount -= 1
s.close()
现在,服务器还需要遵守这个新强加的协议。请注意,负值有效地使客户端接收无限个三元组,这是有意的。以下是修改后的服务器:
import socket
import struct
def to_signed(n):
return n - ((0x80 & n) << 1)
mouse = open('/dev/input/mouse0')
host = ''
port = 29876
backlog = 5
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host, port))
s.listen(backlog)
print 'Listening'
while True:
client, address = s.accept()
# Obtain the number of triplets the client wants.
amount = struct.unpack('!i', recv(client, 4))[0]
while amount: # Send the triplets as they become available.
status, dx, dy = map(ord, mouse.read(3))
dx, dy = to_signed(dx), to_signed(dy)
print status, dx, dy
client.sendall(struct.pack('!bbb', status, dx, dy))
amount -= 1
client.close()
导入套接字
导入结构
def至_签名(n):
返回n-((0x80&n)任何通信的基础都是一个公共协议的协议,因此双方都可以理解正在通信的内容。当使用套接字执行网络通信时,通常以公共格式打包数据,以便另一方可以解包并理解发送的内容。在Python中,这是使用struct
模块。如果您想从某个设备连续发送数据,通常的方法是首先让客户端请求。然后服务器开始发送数据。@mmpg感谢您的代码,它工作得很好PS:很抱歉延迟回复注意(假设状态设置为2),发送(str(status))
将发送类似于\x32\x00
的内容,其中另一方可能正在等待\x00\x02
或\x02\x00
(取决于协议的字节顺序协议)。@TinyT这是正确的。在这种情况下,您应该在结构中使用pack
。
import sys
import socket
import struct
serv_host = ''
serv_port = 29876
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((serv_host, serv_port))
# Tell the server how many triplets I want.
amount = int(sys.argv[1])
s.sendall(struct.pack('!i', amount))
pack_size = struct.calcsize('!bbb')
while amount:
status, dx, dy = struct.unpack('!bbb', recv(s, pack_size))
print status, dx, dy
amount -= 1
s.close()
import socket
import struct
def to_signed(n):
return n - ((0x80 & n) << 1)
mouse = open('/dev/input/mouse0')
host = ''
port = 29876
backlog = 5
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host, port))
s.listen(backlog)
print 'Listening'
while True:
client, address = s.accept()
# Obtain the number of triplets the client wants.
amount = struct.unpack('!i', recv(client, 4))[0]
while amount: # Send the triplets as they become available.
status, dx, dy = map(ord, mouse.read(3))
dx, dy = to_signed(dx), to_signed(dy)
print status, dx, dy
client.sendall(struct.pack('!bbb', status, dx, dy))
amount -= 1
client.close()