我正在使用套接字server-client在python中编程。当我通过使用receive函数从客户端接收服务器时:
someSocket.recv()
是否有可能接收到未知对象?或者我必须注意从套接字收到的数据大小吗?
答案 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简单的库来满足我的所有网络需求。它声称对游戏很有用,但它可以用于任何事情。