2015-12-15 42 views
1

我目前有一个Python客户端&服务器通过套接字发送json对象如下。通过Python中的套接字发送各种类型的数据

客户

# Create the socket & send the request 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
print 'Connecting to server at host: ' + (self.host) + ' port: ' + str(self.port) 
s.connect((self.host, self.port)) 
print 'Sending signing request to the server' 
s.sendall(request_data) 
print 'Waiting for server response' 
response_data = s.recv(10 * 1024) 
print 'Got server response' 
s.close() 

服务器

# Create a socket 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
print 'Starting the server at host: ' + (self.host) + ' port: ' + str(self.port) 
s.bind((self.host, self.port)) 
s.listen(1) 

while True: 
    # Create a new connection 
    print 'Listening for client requests...' 
    conn, addr = s.accept() 
    print 'Connected to: ' + str(addr) 

    # Get the data 
    request_data = conn.recv(10 * 1024) 
    print 'Got message: ' + str(request_data) 

    # Get the json object 
    try: 
     # Decode the data and do stuff 
     # ... 
     # ... 
    except Exception as e: 
     print e 
    finally: 
     # Close the connection 
     conn.close() 

然而,除了JSON对象,我还需要发送一个文件(这是不是一个JSON对象)。在服务器的while循环中,套接字无法区分json对象何时结束和文件开始接收。

我在这里的问题是关于方法。通过套接字发送两种不同类型的数据的常用方法是什么?我们可以使用相同的套接字以串行顺序接收两种数据类型吗?这将需要两个while循环(一个用于json,另一个用于文件)在当前while循环内吗?

或者还有其他方式吗?

谢谢。第一

+0

的最好的办法是使用比原始套接字一个更高层的协议,所以真正的问题是,你为什么要重新发明轮子?你必须有一个很好的理由,因为不要使用[paramiko](http://www.paramiko.org/)这样的SSH/SFTP协议,或者使用HTTP/FTP和[twisted](https:// twistedmatrix的.com/TRAC /)。 –

回答

1

第一件事,你不能只是做

response_data = s.recv(10 * 1024) 
print 'Got server response' 

# Get the data 
request_data = conn.recv(10 * 1024) 
print 'Got message: ' + str(request_data) 

,然后说你已经得到的数据。 Transmissions over TCP do not preserve their borders

关于方法学,您需要一个基于TCP的协议。如果您不需要服务器连接到没有请求的客户端,HTTP将是一个很好的选择。在这种情况下,伟大的库和框架是可用的。

如果您想构建自己的协议,请考虑在数据流中使用控制字符。这样的事情是可能的:

json = b"{foo: ['b', 'a', 'r']}\n" # \n here stands for end-of-the-json symbol 
sock.send_byte(TYPE_JSON_MESSAGE) 
sock.sendall(json) 

sock.send_byte(TYPE_FILE_MESSAGE) 
sock.send_int(file_size) # so the server can determine where the file transmission ends 
for chunk in chunked_file: 
    sock.sendall(chunk) 

这是由你来实现send_bytesend_int。如果你使用struct模块,这并不是很难。

在服务器端:

message_type = sock.recv(1) 
if message_type == TYPE_JSON_MESSAGE: 
    # ... 
elif message_type == TYPE_FILE_MESSAGE: 
    file_size = sock.recv_int() # not implemented 
    # ... 
相关问题