I have a server listening to all the clients that are connected to it, and each client should have this "username" they are identified by, but I'm stuck here... when a client wants to send a message to another client, they send the other client's username as the first word in the message sent to the server. Then I wouldn't know how to direct the message to the right socket (the receiving client). How should I link a client to its socket?? so I can call socket.send??
I'm currently modifying the code from this website: http://www.binarytides.com/code-chat-application-server-client-sockets-python/
Thanks!
def broadcast_data (sock, message):
#Do not send the message to master socket and the client who has send us the message
for socket in CONNECTION_LIST:
if socket != server_socket and socket != sock :
try :
socket.send(message)
except :
# broken socket connection may be, chat client pressed ctrl+c for example
socket.close()
CONNECTION_LIST.remove(socket)
This function could be used as a starting point for a send function
def send_data (sock, message):
#send message to only one client
#sock is the socket of the client to send to
try :
sock.send(message)
except :
# broken socket connection may be, chat client pressed ctrl+c for example
sock.close()
CONNECTION_LIST.remove(socket)
then you could have a dictionary of sockets associating them with a user name
usernameSockets={}
usernameSockets[username]=socket_for_user_name
then you could call the send_data function like
send_data(usernameSockets[username],message)
In the code you linked to there is no method for getting a username so you would have to have the clients send their username to the server when they are connecting to be able to populate a dictionary like the one I have mentioned above.
Related
Help me figure out how to implement it correctly.
The bottom line: The client is charging stations that connect, open a socket and send messages to the server and receive responses.
Server - listens to the port, sees the connected station, receives messages and sends responses to them.
Question: When the client connects and sends headers, I can send a message to the client. But I need to periodically send messages to the client that keeps the socket open, I don't understand how to implement this. Can someone tell me?
sample sending code:
charge_point_id = path.strip('/')
cp = client_main(charge_point_id, websocket)
logging.info(charge_point_id)
print(charge_point_id)
print(path)
await websocket.send(json.dumps([2,"222", "GetLocalListVersion", {}]))
await cp.start()
example of receiving a message from a client:
class client_main(cp):
errors = False
if not errors:
#on('BootNotification')
def on_boot_notitication(self, charge_point_vendor, charge_point_model,charge_point_serial_number,firmware_version,
meter_type, **kwargs):
return call_result.BootNotificationPayload(
status="Accepted",
current_time=date_str.replace('+00:00','Z'),
interval=60
)
in this case, the charging station according to the ocpp protocol opens the connection and keeps it open, it should be possible to somehow write to him
how do i send a message to the client? My example:
#on('Heartbeat')
def on_getlocallistversion(self):
await self.route_message(json.dumps([2,"222","GetLocalListVersion",{}]))
def on_hearbeat(self):
return call_result.HeartbeatPayload(
current_time=datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S')+"Z"
)
I get an error:
await self.route_message(json.dumps([2,"222",
"GetLocalListVersion",{}]))
This is impossible to do. You can send a message only when the client is connected.
The title explain everything. I made Java code that sends messgaes for the python server, but evry time, just the first message is sends because every time, java conneced again to server, and the server keeps waiting to next message from the first client that I send in the first time.
How can the server get message from all clients are connectd? and not just from one?
My python server:
server = socket.socket()
server.bind((socket.gethostname(), 4786))
server.listen(5)
(client, (ipNum, portNum)) = server.accept()
print("Client connected")
while True:
message = str(client.recv(64).decode()) # Check if client send message. I want to change it to check all clients
if(message != ""):
print("Client: " + message)
else:
time.sleep(0.1)
Summary
The server.accept() must be called inside the loop.
TLDR
The socket server returned from the call socket.socket() is a 'listening' socket. It is not used for any data transfer but just for listening incoming connections. When the server is willing to accept incoming connection then calls server.accept(). This call waits till a client connects. When a client connects the accept wakes up and returns a socket that represents a connection to one client. This socket is then used for data send and received and should be closed when the communication with this specific client is done.
When server wants to accept connection from another client it must call server.accept() again to wait for connection from another client and use the unique client socket for each connected client.
If it sufficient to handle client sequentially then you can just move the call accept onto the loop. Furthermore you should close the client socket when the communication with the client is done.
If multiple clients can be connected in parallel then slightly more complicated design is needed. You can start a new thread for each client after accepting the connection. The thread can call recv in a loop and terminates when the client disconnects. See Multi Threaded TCP server in Python for example.
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 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
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.