Python使用套接字方法recv

时间:2014-03-09 16:22:59

标签: python sockets

我正在使用套接字server-client在python中编程。当我通过使用receive函数从客户端接收服务器时:

someSocket.recv()

是否有可能接收到未知对象?或者我必须注意从套接字收到的数据大小吗?

3 个答案:

答案 0 :(得分:1)

对于简单的沟通,您需要某种序列化。对于简单的通信,我经常将套接字转换为像对象这样的文件,然后我使用一些文本简单的协议,如pickle或json。使用pickle,或者如果你想通过线路发送人类可读文本,然后发送单行非包装jsons并使用换行符终止每个对象。在python的情况下,pickle给你更多的自由,因为json对被认为是有效的数据有一些限制。

简单的pickle和基于json的服务器 - 客户端示例:

client.py:

import socket, pickle

def socket_to_file(sock):
    try:
        sock.settimeout(15)
        return sock.makefile()
    finally:
        sock.close()

if __name__ == '__main__':
    sock = socket.create_connection(('localhost', 3005))
    sock = socket_to_file(sock)
    try:
        request = {
            'param0': True,
            'param2': 'sztringecske',
        }
        print 'Sending request: %s' % (request,)
        pickle.dump(request, sock)
        sock.flush()    # important!!!
        response = pickle.load(sock)
        print 'Received response: %s' % (response,)
    finally:
        sock.close()

server.py:

import socket, pickle

def socket_to_file(sock):
    try:
        client_sock.settimeout(15)
        return sock.makefile()
    finally:
        sock.close()

if __name__ == '__main__':
    listen_sock = socket.socket()
    try:
        listen_sock.bind(('', 3005))
        listen_sock.listen(10)
        client_sock, client_addr = listen_sock.accept()
    finally:
        listen_sock.close()

    try:
        client_sock = socket_to_file(client_sock)
        request = pickle.load(client_sock)
        print 'Request: %s' % (request,)
        response = 'My smart response.'
        print 'Response: %s' % (response,)
        pickle.dump(response, client_sock)
        client_sock.flush()
    finally:
        client_sock.close()

json_client.py:

import socket, json

def socket_to_file(sock):
    try:
        sock.settimeout(15)
        return sock.makefile()
    finally:
        sock.close()

if __name__ == '__main__':
    sock = socket.create_connection(('localhost', 3005))
    sock = socket_to_file(sock)
    try:
        request = {
            'param0': True,
            'param2': 'sztringecske',
        }
        print 'Sending request: %s' % (request,)
        sock.write(json.dumps(request))
        sock.write('\n')
        sock.flush()    # important!!!
        response = json.loads(sock.readline())
        print 'Received response: %s' % (response,)
    finally:
        sock.close()

json_server.py:

import socket, json

def socket_to_file(sock):
    try:
        client_sock.settimeout(15)
        return sock.makefile()
    finally:
        sock.close()

if __name__ == '__main__':
    listen_sock = socket.socket()
    try:
        listen_sock.bind(('', 3005))
        listen_sock.listen(10)
        client_sock, client_addr = listen_sock.accept()
    finally:
        listen_sock.close()

    try:
        client_sock = socket_to_file(client_sock)
        request = json.loads(client_sock.readline())
        print 'Request: %s' % (request,)
        response = 'My smart response.'
        print 'Response: %s' % (response,)
        client_sock.write(json.dumps(response))
        client_sock.write('\n')
        client_sock.flush()
    finally:
        client_sock.close()

如何检测您收到的数据类型?最好的是你不必检测。使用上述解决方案,您可以发送{'command': 'delete', 'delete_param': 'delete_specific_param' }等复杂对象。如果您定义协议以便发送到服务器的消息始终包含command密钥,则服务器可以始终检查此信息并根据实际命令解释其余数据。如果您仍然坚持发送int之类的原始对象,那么在收到响应之后,您只需使用isinstance(response, int)来检查响应是否为整数。

效率:这些解决方案通过写入发送文本数据,但不要害怕,很少需要过度优化的网络通信。这些解决方案非常适合将简单的客户端服务器组合在一起。

答案 1 :(得分:0)

根据您的评论,我了解您想知道收到的数据是整数还是字符串。收到数据后,您可以将其分配给变量。然后,您可以使用isdigit()isinstance等各种方法来了解它是字符串,整数还是浮点数。

示例

Test = "123"
if Test.isdigit() == True:
    print "Test is an integer"
else:
    print "Test is not an integer"

如果您想知道它是不是浮动,那么您可以尝试使用isinstance

>>> x = 123
>>> isinstance(x, int)
True
>>> y = 123.01
>>> isinstance(y, float)
True

您可以将这两种方法结合起来,并创建一种新方法来实现这一切。

答案 2 :(得分:0)

套接字仅发送和接收字节对象。您可以通过带有 pickle 的套接字发送对象(请记住,pickle 安全)。您可以使用 isinstance()

来测试对象的类型
data= sock.recv(1024)
obj= pickle.loads(data)
isInt= isinstance(obj, int)

如果要将其转换为字符串,则需要解码字节:

data= sock.recv(1024)
strdata= data.decode('utf-8')

以1024为增量接收数据是一种很好的做法,如果要发送的数量超过该数量,则必须创建循环结构。就个人而言,套接字对我来说太低了,我使用this简单的库来满足我的所有网络需求。它声称对游戏很有用,但它可以用于任何事情。