UDP server can't send packet to the client - python

I have two computer(A and B) in the different VLAN.
the IP of the computer A server is x.x.180.70 and IP of the computer B is x.x.181.52.
the computer A bind 19999 port as the UDP server and B as the client.
A can recv the packet from B, but B can't recv the packet from A.
so i capture the packet with wireshark, the results shown that the server reply packet with another port. In common the server reply packet with the bound port. Why does the server use the different port?
Then I wrote a TCP Server on computer A, it works well.
The udp server works if A and B at the same vlan. Is there any body have idea? thanks!
Code(Python):
#!/usr/bin/python3
#coding=utf-8
import socket
import sys
def server(addr):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(addr)
print("server started, listen on %s" % str(addr))
while True:
print("wait msg....")
data, cconn = sock.recvfrom(1024)
client_addr = "%s:%d" % (cconn[0], cconn[1])
resp = "hello client"
print("recv msg from %s <- %s" % (client_addr, data.decode('utf-8')))
sock.sendto(resp.encode("utf-8"), cconn)
print("send msg to %s -> %s" % (client_addr, resp))
def client(addr):
server_addr = "%s:%d" % (addr[0], addr[1])
print("send msg to %s" % server_addr)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.connect(addr)
sock.sendto("hello server".encode("utf-8"), addr)
data, conn = sock.recvfrom(1024)
resp = data.decode("utf-8")
print("recv msg from %s <- %s" % (server_addr, resp))
def usage():
print("Usage:")
print(" python3 udp.py server [ip:port]")
print(" python3 udp.py client [ip:port]")
if __name__ == "__main__":
if len(sys.argv) < 3:
usage()
exit(0)
role = sys.argv[1]
array = sys.argv[2].split(":")
address = (array[0], int(array[1]))
if role == "server":
server(address)
elif role == "client":
client(address)
else:
usage()

Related

Python socket - how to save data from two clients separately

Here's the code, I wonder how to save the messages separately.
It can only get and send messages back to client. But I can't distinguish which are from client 1 and which are from client 2. Is there any way to save these messages into separate list or something else? so that I can distinguish them
Client 1:
import socket
import sys
messages = [b'This is client 1',
b'It is a good day!',
]
server_address = ('localhost', 1234)
socks = [ socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
for i in range(1)]
print('connecting to %s port %s' % server_address)
for s in socks:
s.connect(server_address)
for message in messages:
for s in socks:
s.send(message)
for s in socks:
data = s.recv(1024)
print(data.decode())
if not data:
print(sys.stderr, 'closing socket', s.getsockname())
Client 2:
import socket
import sys
messages = [b'This is client 2',
b'It is raining today',
]
server_address = ('localhost', 5678)
socks = [ socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
for i in range(1)]
print('connecting to %s port %s' % server_address)
for s in socks:
s.connect(server_address)
for message in messages:
for s in socks:
s.send(message)
for s in socks:
data = s.recv(1024)
print(data.decode())
if not data:
print(sys.stderr, 'closing socket', s.getsockname())
Server:
import selectors
import socket
sel = selectors.DefaultSelector()
def accept(sock, mask):
conn, addr = sock.accept()
print('accepted', conn, 'from', addr)
conn.setblocking(False)
sel.register(conn, selectors.EVENT_READ, read)
def read(conn, mask):
data = conn.recv(1000)
if data:
conn.send(data)
else:
print('closing', conn)
sel.unregister(conn)
conn.close()
sock = socket.socket()
sock.bind(('localhost', int(input())))
sock.listen(1)
sock.setblocking(False)
sel.register(sock, selectors.EVENT_READ, accept)
while True:
events = sel.select()
for key, mask in events:
callback = key.data
callback(key.fileobj, mask)
If you want to validate the ip on the network layer then you can use the variable addr that you create when you accept the connection.
However when you are doing this with multiple clients on the same host then it will not work since the ip is the same.
This will also not work if you are behind a NAT, because you would just get the IP of the nearest router in your network.
Another solution would be to validate the client on the application layer and simply give the client an identification value that you pass into the message that you send from the client.

Python socket client doesnt receive anything, hangs by recv.from(datasize)

I have to make a simple udp echo client and server, currently my problem is that the client hangs itself up at the code "data, address = sock.recvfrom(dataSize)". Here is my client and server code (I removed some api functions, so it aint long). I tried same ports and different ports and the same goes with the ip's but i dont get any message back. I tried the original file from a friend and his version works, I have the same port and ip and the same methods on both files, but it still keeps hanging at the echoClient method receiveMSG at the first line.
echoServerUDP.py
0<0# : ^
'''
#echo off
python "%~f0" %*
pause
exit /b 0
'''
#!/usr/bin/env python
import socket
import json
host = '0.0.0.0'
sport = 11111 # own port
dataSize = 1024
ip_adresses = {}
def echo_server():
receiveSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
receiveSock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
receiveSock.bind((host,sport))
print("Starting up echo server on %s port %s" % (host, sport))
while True:
print("Waiting to receive message")
print("Generate a Session ...")
data, address = receiveSock.recvfrom(dataSize)
data = data.decode("utf-8")
if data:
print("receive data: %s from %s" % (data,address))
json_object = json.loads(data)
operation=json_object["operation"]
if operation == "register":
register(json_object["name"],json_object["value"],json_object["sid"])
json_message={"ergebnis":"ok"}
dump = json.dumps(json_message)
sendMSG(bytes(dump,encoding="utf-8"),address)
print("er")
if operation == "unregister":
unregister(json_object["name"],json_object["sid"])
if operation == "query":
query(json_object["sid"])
if operation == "reset":
reset(json_object["sid"])
print("sent %s bytes back to %s" % (data,address))
def sendMSG(data,address):
sendSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sendSock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sendSock.sendto(data,address)
sendSock.close()
if __name__ == '__main__':
echo_server()
and here the echoClientUDP.py
0<0# : ^
'''
#echo off
python "%~f0" %*
pause
exit /b 0
'''
#!/usr/bin/env python
import socket
import time
import json
from random import randint
host = '127.0.0.1'
sport = 11111
dataSize = 1024
sid= randint(1,10000)
name=socket.gethostname()
own_ip = socket.gethostbyname(name)
def echo_client():
sendSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
json_message = {"operation":"register","name":name,"value":own_ip,"sid":sid}
dump = json.dumps(json_message)
print("Sending %s to %s:%s" % (dump,host,sport))
sendMSG(sendSock, dump)
data = receiveMSG(sendSock)
if data:
print("Received: %s" % data)
except Exception as err:
print("Socket error: %s" %str(err))
finally:
print("Closing connection to the server")
sendSock.close()
def sendMSG(sendSock, data):
sendSock.connect((host, sport))
sendSock.sendall(bytes(data,encoding="utf-8"))
def receiveMSG(sock):
data, address = sock.recvfrom(dataSize)
print(data)
return data
if __name__ == '__main__':
echo_client()
Please put more effort in some areas like you have not added any headers and you have gone more complicated i have also created a similar working script see and observe that script and make changes to your script
client.py :-
import socket
import sys
HEADER = 64
PORT = 65432
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT"
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(ADDR)
def send(msg):
message = msg.encode(FORMAT)
msg_length = len(message)
send_length = str(msg_length).encode(FORMAT)
send_length += b' ' * (HEADER - len(send_length))
client.send(send_length)
client.send(message)
print(client.recv(2048).decode(FORMAT))
def chat():
while True:
try:
a = input()
if 'quit' in a:
sys.exit()
else:
send(a)
except Exception as e:
print(e)
sys.exit()
chat()
server.py :-
import socket
import threading
HEADER = 64
PORT = 65432
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "Bye"
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
def handle_client(conn, addr):
print(f"[NEW CONNECTION] {addr} connected.")
connected = True
while connected:
msg_length = conn.recv(HEADER).decode(FORMAT)
if msg_length:
msg_length = int(msg_length)
msg = conn.recv(msg_length).decode(FORMAT)
if msg == DISCONNECT_MESSAGE:
connected = False
print(f"[{addr}] left")
print(f"[{addr}] {msg}")
conn.send("Msg received".encode(FORMAT))
conn.close()
def start():
server.listen()
print(f"[LISTENING] Server is listening on {SERVER}")
while True:
conn, addr = server.accept()
thread = threading.Thread(target=handle_client, args=(conn, addr))
thread.start()
print(f"[ACTIVE CONNECTIONS] {threading.activeCount() - 1}")
print("[STARTING] server is starting...")
start()
and i have used threading here to make the process more fast.
First run the server.py in background and then run client.py to connect to the server.

TCP Multi-Thread Server

I am ttrying to implement a multithread TCP server using Python. When I run the following code I obtain the following error:
Error
Incoming message: how are you
Unhandled exception in thread started by <function client_thread at 0x00000000024499 E8>
Traceback (most recent call last):
File "tcp_test2.py", line 32, in client_thread
message = recv_msg(conn)
File "tcp_test2.py", line 24, in recv_msg
raw_msglen = recvall(sock, 4)
File "tcp_test2.py", line 13, in recvall
raise EOFError('was expecting %d bytes but only received %d bytes before socket closed' % (length, len(data)))
EOFError: was expecting 4 bytes but only received 0 bytes before socket closed
Not sure where I am going wrong with implementing the threading function. Any help would be greatly appreciated.
Code
import argparse
import socket
import struct
from thread import start_new_thread
def recvall(sock, length):
data = b''
while len(data) < length:
packet = sock.recv(length - len(data))
if not packet:
raise EOFError('was expecting %d bytes but only received %d bytes before socket closed' % (length, len(data)))
data += packet
return data
def send_msg(sock, msg):
msg = struct.pack('>I', len(msg)) + msg
sock.sendall(msg)
def recv_msg(sock):
raw_msglen = recvall(sock, 4)
if not raw_msglen:
return None
msglen = struct.unpack('>I', raw_msglen)[0]
return recvall(sock, msglen)
def client_thread(conn):
while True:
message = recv_msg(conn)
print('Incoming message: {}'.format(message))
conn.sendall(b'Message Received') #send data to the socket
conn.close() #mark the socket closed
print('\tReply sent, socket closed')
Server
def server(interface, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((interface, port)) # the socket to address
sock.listen(1) #listen for connections made to the socket.
while True:
conn, sockname = sock.accept()
start_new_thread(client_thread,(conn,))
sock.close()
Client
def client(host, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
print('Client has been assigned socket name', sock.getsockname())
message = raw_input("Type your message: ")
send_msg(sock, message)
reply = recvall(sock, 16)
print('Server Response: {}'.format(reply))
print('\nSocket closed')
sock.close()
if __name__ == '__main__':
choices = {'client': client, 'server': server}
parser = argparse.ArgumentParser(description='Send and receive over TCP')
parser.add_argument('role', choices=choices, help='which role to play')
parser.add_argument('host', help='interface the sever listens at:' 'host the client sends to')
parser.add_argument('-p', metavar='PORT', type=int, default=1060, help='TCP port(default 1060)')
args = parser.parse_args()
function = choices[args.role]
function(args.host, args.p)
This is my previous code which did not have any unhandled exceptions
import argparse
import socket
import struct
def recvall(sock, length):
data = b''
while len(data) < length:
packet = sock.recv(length - len(data))
if not packet:
raise EOFError('was expecting %d bytes but only received %d bytes before socket closed' % (length, len(data)))
data += packet
return data
def send_msg(sock, msg):
msg = struct.pack('>I', len(msg)) + msg
sock.sendall(msg)
def recv_msg(sock):
raw_msglen = recvall(sock, 4)
if not raw_msglen:
return None
msglen = struct.unpack('>I', raw_msglen)[0]
return recvall(sock, msglen)
def server(interface, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((interface, port)) # the socket to address
sock.listen(1) #listen for connections made to the socket.
print('Listening at {}'.format(sock.getsockname())) #returns the socket's own address
while True:
conn, sockname = sock.accept()
print('Connection accepted from {}'.format(sockname))
print('\tServer Socket: {}'.format(conn.getsockname()))
print('\tClient Socket: {}'.format(conn.getpeername())) # return remote address to which socket is connected
message = recv_msg(conn)
print('Incoming message: {}'.format(message))
conn.sendall(b'Message Received') #send data to the socket
conn.close() #mark the socket closed
print('\tReply sent, socket closed')
def client(host, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
print('Client has been assigned socket name', sock.getsockname())
message = raw_input("Type your message: ")
send_msg(sock, message)
reply = recvall(sock, 16)
print('Server Response: {}'.format(reply))
print('\nSocket closed')
sock.close()
if __name__ == '__main__':
choices = {'client': client, 'server': server}
parser = argparse.ArgumentParser(description='Send and receive over TCP')
parser.add_argument('role', choices=choices, help='which role to play')
parser.add_argument('host', help='interface the sever listens at:' 'host the client sends to')
parser.add_argument('-p', metavar='PORT', type=int, default=1060, help='TCP port(default 1060)')
args = parser.parse_args()
function = choices[args.role]
function(args.host, args.p)
Nothing is wrong. Your client closes the socket. The server detects this when it tries to read the next message. This should have been exactly what you expected.

Python: Send data to one client from database

I have a python script that receives tcp data from client and I want to send a response to a specific client (I handle more than 500). This command comes from a mysql database and I handle the clientsocket by a dictionary, but the script is down when it receives a lot of connections.
How can I store the clientsocket in mysql database, or which is the best way to handle the clientsocket?
My code is:
import thread
from socket import *
def sendCommand():
try:
for clientsocket,id_client in conn_dict.iteritems():
if id_cliente == "TEST_from_mysql_db":
clientsocket.send("ACK SEND")
break
except:
print "NO"
def handler(clientsocket, clientaddr):
print "Accepted connection from: ", clientaddr
while 1:
data = clientsocket.recv(buf)
if not data:
break
else:
conn_dict[clientsocket] = id_client
sendCommand()
clientsocket.close()
if __name__ == "__main__":
conn_dict = dict()
host = str("XXX.XXX.XXX.XXX")
port = XXX
buf = 1024
addr = (host, port)
serversocket = socket(AF_INET, SOCK_STREAM)
serversocket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
serversocket.bind(addr)
serversocket.listen(2)
while 1:
print "Server is listening for connections\n"
clientsocket, clientaddr = serversocket.accept()
thread.start_new_thread(handler, (clientsocket, clientaddr))
serversocket.close()

Python sockets - send variable back to client from server

I am using sockets for a client / server application, where I need to send a variable from the server back to the client when the use clicks a button, for example. I am using wxpython.
Here is a sample of my server code:
def handler(self, clientsocket, clientaddr):
data22 = clientsocket.recv(1024)
while 1:
msg = "Message to send"
clientsocket.sendall(msg)
clientsocket.close()
def listen(self):
host = ''
port = 55567
buf = 1024
addr = (host, port)
self.serversocket = socket(AF_INET, SOCK_STREAM)
self.serversocket.bind(addr)
self.serversocket.listen(2)
while 1:
if self.canExit:
print "trying to break"
break
print "Server is listening for connections\n"
clientsocket, clientaddr = self.serversocket.accept()
threading.Thread(target=self.handler, args=(clientsocket, clientaddr)).start()
print "closing the socket"
self.serversocket.close()
And here is a sample of my client code:
def SendFolder(self):
HOST = host=self.params["databaseLocation"] # The remote host
port = 55567
buf = 1024
addr = (host, port)
clientsocket = socket(AF_INET, SOCK_STREAM)
clientsocket.connect(addr)
if self.abortThisJob != False:
clientsocket.sendall(self.abortThisJob)
else:
clientsocket.sendall("Send Job")
self.listenThread = threading.Thread(target=self.listen, args=(clientsocket, buf))
self.listenThread.daemon= True
self.listenThread.start()
def listen(self, clientsocket, buf):
while 1:
data = raw_input(">> ")
clientsocket.send(data)
data = clientsocket.recv(buf)
print data

Categories