Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中的套接字编程_Python_Sockets - Fatal编程技术网

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()