I am trying to use socketserver to create a simple server to send images to a client with TCP.
First I send a catalogue to the client and then it responds with a request.
In the handle of my server, I have this loop :
class MainHandler(socketserver.BaseRequestHandler):
def handle(self):
while 1:
try:
# Sending the catalogue
# Using my methods to get my catalogue with a HTTP header
response = self.server.genHTTPRequest(self.server.init.catalogue)
self.request.sendall(response.encode())
# Response of the client
self.data = self.request.recv(1024).decode()
if self.data:
print("Data received : {}".format(self.data))
except:
print("transmission error")
break;
In the main I use this line to create my server (it's in an other file) :
mainServer = MainServer.MainServer((init.adresse, int(init.port)), MainServer.MainHandler)
When I launch this program, the client connect successfully and receive the catalogue but it sends back only some data and the program jump in the exception of the try/catch. Without the try/catch, I got this error :
self.data = self.request.recv(1024).decode()
ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine
I don't understand what is the problem, maybe a synchronization missing or may I need to use threads ?
Thank you for your help
(I am using python 3.3)
The problem would be because of sendall(response.encode()) and this self.request.recv(1024).decode() has been done in the same socket and it could lead to ConnectionAbortedError.
You need to read all the data from the socket before putting other data into the socket. Like flushing of data.
Related
I am trying to send an array of messages through the same socket connection, but I get an error.
Here is my client code:
def send_over_socket(hl7_msg_array):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((config.HOST, config.PORT))
for single_hl7_msg in hl7_msg_array:
sock.send(single_hl7_msg.to_mllp().encode('UTF-8'))
received = sock.recv(1024*1024)
print("Sent: ", received)
sock.shutdown()
sock.close()
While debugging the code, I see that the exception occurs when I call the sock.recv(1024*1024) for the second message.
Here is the error:
ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine
Server-side code:
def run_mllp_server():
class PDQHandler(AbstractHandler):
def reply(self):
msg = hl7.parse(self.incoming_message)
msg_pid = msg[1][3]
msg_key = msg[2][3][0][1]
msg_value = msg[2][5]
lock = RLock()
lock.acquire()
results_collection[str(msg_pid)][str(msg_key)] = str(msg_value)
lock.release()
print("Received: ", repr(self.incoming_message))
return parse_message(self.incoming_message).to_mllp()
# error handler
class ErrorHandler(AbstractErrorHandler):
def reply(self):
if isinstance(self.exc, UnsupportedMessageType):
print("Error handler success 1")
else:
print("Error handler else case")
handlers = {
'ORU^R01^ORU_R01': (PDQHandler,),
'ERR': (ErrorHandler,)
}
server = MLLPServer(config.SOCKET_HOST, config.SOCKET_PORT, handlers)
print("Running Socket on port ", config.SOCKET_PORT)
server.serve_forever()
Here I am using MLLP protocol which has a TCP connection behind the scenes.
Can you help me please figure out what is going on? Is it a problem of ACK?
I do not know python at all but...
I do not think multiple messages is your problem. Looking at exception, I guess your first message is being sent correctly. Then, your client code waits for ACK to be received; but server never sends it. It instead closes the connection.
Also, make sure that whether sendall should be used instead of send.
After above issue is fixed, to send multiple messages on same connection, you have to follow MLLP (also called LLP) so that server can differentiate the message.
Description HEX ASCII Symbol
Message starting character 0B 11 <VT>
Message ending characters 1C,0D 28,13 <FS>,<CR>
This way, when you send a message to Listener (TCP/MLLP server), it looks for Start and End Block in your incoming data. Based on it, it differentiates each message.
Please refer to this answer for more details.
I'm trying to build a very simple TELNET client in Python and I'm getting problem on the last part: sending/receiving data to/from the server.
With the code I have, if no data arrives at the very beginnig, the loop get paused and I can't even send commands.
Here the interested part of the code:
# Infinite cycle that allows user to get and send data from/to the host
while True:
incoming_data = my_socket.recv(4096)
if not incoming_data:
print('Problem occurred - Connection closed')
my_socket.close()
sys.exit()
else:
# display data sent from the host trough the stdout
sys.stdout.write(incoming_data)
# Commands sent to the host
command = sys.stdin.readline()
my_socket.send(command)
(I think the program kinda of works if I try to connect to some hosts that send data at the beginning.)
The idea would be have two loops, running at the same time, getting data or sending data, but I can't get it to work.
I can't use the telnet library and I don't want to use the select library (only sys and socket).
You want to use the threading library.
The following program runs the receiving in one thread and the sending in another:
import socket
from threading import Thread
def listen(conn):
while True:
received = conn.recv(1024).decode()
print("Message received: " + received)
def send(conn):
while True:
to_send = input("Input message to send: ").encode()
conn.sendall(to_send)
host = "127.0.0.1"
port = 12345
sock = socket.socket()
sock.connect((host, port))
Thread(target=listen, args=[sock]).start()
Thread(target=send, args=[sock]).start()
This program is for Python 3. Python 2 is very similar, except print() works differently, and you don't need to encode() and decode() everything being sent through a socket.
The listen and send functions are run in parallel, so that as soon as data arrives, it is printed, but you can also send data at any time. Practically, you would probably want to make some changes so that the data isn't just printed over the input prompt. However, this would be hard just in a command line application.
Research queues for control over data passing between threads.
Let me know if you have any more questions.
I made a python socket server recently that listens on port 9777 the server is suppose to accept connections and once it does will allow you to send information to the client. The client will then print out whatever it received. However, I found that after I sent some data the server would hang until i reinitialized a new connection. Is there a reason for this and if so how can I prevent it from happening
The code of the server is :
import socket
import sys
host='0.0.0.0'
port=9777
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind((host,port))
s.listen(10)
c,a=s.accept()
while True:
command=raw_input('[input>] ')
if 'data' in command:
c.send('continue')
data=c.recv(1024)
print data
else:
continue
the code will only send data if the word data is in the string. Here is the code for the client:
import socket
import sys
host='192.168.0.13'
port=9777
while True:
try:
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((host,port))
except:
continue
while True:
d=s.recv(9999)
print d
s.send('received')
My goal is to setup a connection between server and client. I want the server to be able to accept input from a user in a while loop and send the input to the client. The client needs to be able to receive information and when it does it will send a response to the server. Then the user can continue sending data to the server until they decide to terminate the program. However the server keeps hanging after sending data once to the client. Can anyone tell me how I can prevent that?
I try this code in my computer it's work fine , maybe you need to change host='192.168.0.13' to host='localhost'
and host='0.0.0.0' to host='localhost'
look at this picture
and if this problem stay maybe your ip address is the same of other device in the network for that try to run this command ipconfig /renew
I was reading about the Python websocket-client library and realized that, to receive data, we have to start a connection:
from websocket import create_connection
ws = create_connection("ws://echo.websocket.org/")
print "Received " + ws.recv() + "..."
What if I just need a one-way connection? Say a Python script is running on my laptop, and it periodically sends messages to a local web server.
To receive messages, the web server would have to start a connection, but starting a connection requires a URL to connect to. My Python script is not a web server, so it lacks a URL. How could the web server receive messages from the script?
I tried to let the server listen for clients to connect with it via
ws = websocket.WebSocket()
while 1:
print 'received "' + ws.recv()
However, I get an error.
in _recv
bytes = self.io_sock.recv(bufsize)
error: [Errno 107] Transport endpoint is not connected
That error output leads me to believe that the server needs to connect in order to receive.
If you would want one way connection to the server, you could just listen on plain socket or use UDP or use HTTP requests ore any other TCP protocol.
For a class assignment I need to use the socket API to build a file transfer application. For this project there two connections with the client and server, one is called the control and is used to send error messages and the other is used to send data. My question is, on the client side how can I keep the control socket open and waiting for any possible error messages to be received from the server while not blocking the rest of the program from running?
Example code (removed some elements)
#Create the socket to bind to the server
clientSocket = socket(AF_INET,SOCK_STREAM)
clientSocket.connect((serverName,portNum))
clientSocket.send(sendCommand) # Send to the server in the control connection contains either the list or get command
(If command is valid server makes a data connection and waits for client to connect)
clientData = socket(AF_INET,SOCK_STREAM)
clientData.connect((serverName,dataport)) #Client connects
recCommand = clientData.recv(2000) #Receive the data from server if command is successful
badCommand = clientSocket.recv(2000) #But if there is an error then I need to skip the clientData.recv and catch the error message in bad Command
when there is an error, the data-socket should be closed by the server, so recv ends automatically.