Source code for pySPACE.tools.socket_utils
#!/usr/bin/env python
# encoding: utf-8
"""
Provide often needed functions when dealing with the Python socket module
** Functions **
:receive:
Return a full message read from a socket connection
:inform:
Send a message to a socket connection
:talk:
Send a message to a socket connection and return the answer
:Author: Anett Seeland (anett.seeland@dfki.de)
:Created: 2012/08/28
"""
import socket
import warnings
import time
import traceback
def _reconnect(ip_port):
"""Return a new socket connection over TCP/IP """
com = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
com.connect(ip_port)
return com
[docs]def receive(conn, end_token="!END!"):
"""Return a full message read from a socket connection"""
full_message = []
msg = ''
while True:
msg = conn.recv(4096)
if end_token in msg:
full_message.append(msg[:msg.find(end_token)])
break
full_message.append(msg)
if len(full_message)>1:
#check if end_of_data was split
last_pair=full_message[-2]+full_message[-1]
if end_token in last_pair:
full_message[-2]=last_pair[:last_pair.find(end_token)]
full_message.pop()
break
return "".join(full_message)
[docs]def talk(to_send, conn=None, ip_port=None):
"""Send a message and return the answer and the connection
If an connection is already established, the message is send to it
and the answer is returned. If the connection is broken and the message
cannot be sent, a new connection is created.
**Parameters**
:to_send:
A String representing the message to send.
:conn:
A client socket where the message is send to.
:ip_port:
A Tuple of IP and port for potentially reconnect.
One of the parameters *conn* or *ip_port* has to be specified.
"""
conn = inform(to_send, conn, ip_port)
if conn != None:
# let server some time to receive all data
time.sleep(0.003)
# receive answer
try:
answer = receive(conn)
except socket.error,e:
warnings.warn(str( time.asctime( time.localtime(time.time()) ))+': recv '+ str(e))
traceback.print_stack()
try:
conn.shutdown(socket.SHUT_RDWR)
except:
pass
conn.close()
time.sleep(0.1)
# try reconnection
if ip_port != None:
new_conn = _reconnect(ip_port)
if "Connection timed out" in str(e):
return talk(to_send,new_conn,ip_port)
else:
return talk(to_send,new_conn)
else:
raise RuntimeError("Communication failed!")
else:
return (conn, answer)
elif ip_port != None:
# establish a connection
conn = _reconnect(ip_port)
return talk(to_send,conn,ip_port)
else:
raise Exception("Specify at least connection or ip/port")