I am writing a python program (master.py) to read the data received from 2 separate clients. This is the code example:
master.py:
data_agg = ''
HOST = '172.31.31.207'
PORT = 50008
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(2)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
data = conn.recv(65535)
data_agg += data
if not data: break
data_arr = json.loads(data_agg.decode('utf-8'))
data_arr = sorted(data_arr)
print "Sorted attay: \n"
print data_arr
Two clients have the following code:
HOST = '172.31.31.207'
PORT = 50008
s0 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s0.connect((HOST, PORT))
s0.send(sorted_data_string)
s0.close()
However i only receive data from a single client. What would be a proper way to read the data from a socket arriving from multiple receivers?
If you want your server th handle multiple clients, you can put accept() in a loop and add new clients to a list of connected clients. Then you can read - write to each of those clients.
HOST = '172.31.31.207'
PORT = 50008
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(2)
clients = []
while True:
conn, addr = s.accept()
clients += [{'conn':conn, 'addr':addr}]
print 'Connected by', addr
data_agg = ''
while True:
data = conn.recv(65535)
if not data:
break
data_agg += data
data_arr = sorted(json.loads(data_agg.decode('utf-8')))
print "Sorted attay: \n"
print data_arr
conn.close()
s.close()
You could improve the above code by using thread, so that you can handle multiple clients at the same time. You can do this by defining a handle_client function, and run it on a new thread.
while True:
conn, addr = s.accept()
print 'Connected by', addr
start_new_thread(handle_client, (conn,))
Related
I am using my server code on a raspberry pi and my client code on my laptop. I also off the firewall on my computer. After connecting to the server, I manage to run the loop for once from the client side by keying the word "data" and when I keyed in another command it just came out of the loop. If i key in Quit it says that it have an OS error98 address already in used. May I know how to keep the loop on going ? Below I is my client.py and server.py code.
Server.py code:
import socket
import numpy as np
import encodings
HOST = '192.168.1.65'
PORT = 65432 # Port to listen on (non-privileged ports are > 1023)
def random_data(): # ANY DATA YOU WANT TO SEND WRITE YOUR SENSOR CODE HERE
x1 = np.random.randint(0, 55, None) # Dummy temperature
y1 = np.random.randint(0, 45, None) # Dummy humidigy
my_sensor = "{},{}".format(x1,y1)
return my_sensor # return data seperated by comma
def my_server():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
print("Server Started waiting for client to connect ")
s.bind((HOST, PORT))
s.listen(5)
conn, addr = s.accept()
with conn:
print('Connected by', addr)
while True:
data = conn.recv(1024).decode('utf-8')
if str(data) == "Data":
print("Ok Sending data ")
my_data = random_data()
x_encoded_data = my_data.encode('utf-8')
conn.sendall(x_encoded_data)
elif str(data) == "Quit":
print("shutting down server ")
break
else:
pass
if __name__ == '__main__':
while 1:
my_server()
Client.py Code:
import socket
import threading
import time
HOST = '192.168.1.65' # The server's hostname or IP address
PORT = 65432 # The port used by the server
def process_data_from_server(x):
x1, y1 = x.split(",")
return x1,y1
def my_client():
threading.Timer(11, my_client).start()
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
my = input("Enter command ")
my_inp = my.encode('utf-8')
s.sendall(my_inp)
data = s.recv(1024).decode('utf-8')
x_temperature,y_humidity = process_data_from_server(data)
print("Temperature {}".format(x_temperature))
print("Humidity {}".format(y_humidity))
s.close()
time.sleep(5)
if __name__ == "__main__":
while 1:
my_client()
address already used
you need to use socket.setsockopt to set socket.SO_REUSEADDR in i think both client and server.py
def my_server():
# with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
print("Server Started waiting for client to connect ")
s.bind((HOST, PORT))
s.listen(5)
conn, addr = s.accept()
with conn:
print('Connected by', addr)
while True:
data = conn.recv(1024).decode('utf-8')
if str(data) == "Data":
...
I have a listener on a tcp localhost:
HOST = '127.0.0.1' # The server's hostname or IP address
PORT = 8192 # The port used by the server
def client_socket():
while 1:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP,TCP_PORT))
s.listen(1)
while 1:
print 'Listening for client...'
conn, addr = s.accept()
print 'Connection address:', addr
data = conn.recv(BUFFER_SIZE)
if data == ";" :
conn.close()
print "Received all the data"
i=0
for x in param:
print x
#break
elif data:
print "received data: ", data
param.insert(i,data)
i+=1
#print "End of transmission"
s.close()
I am trying to send a JSON object to the same port on the local host:
HOST = '127.0.0.1' # The server's hostname or IP address
PORT = 8192 # The port used by the server
def json_message(direction):
local_ip = socket.gethostbyname(socket.gethostname())
data = {
'sender' : local_ip,
'instruction' : direction
}
json_data = json.dumps(data, sort_keys=False, indent=2)
print("data %s" % json_data)
send_message(json_data)
return json_data
def send_message(data):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
s.sendall(data)
data = s.recv(1024)
print('Received', repr(data))
However, I get a socket error:
socket.error: [Errno 98] Address already in use
What am I doing wrong? Will this work or do I need to serialize the JSON object?
There are a few problems with your code, but the one that will likely address your issue is setting the SO_REUSEADDR socket option with:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
after you create the socket (with socket.socket(...) but before you attempt to bind to an address (with s.bind().
In terms of other things, the two "halves" of the code are pretty inconsistent -- like you copied and pasted code from two different places and tried to use them?
(One uses a context manager and Python 3 print syntax while the other uses Python 2 print syntax...)
But I've written enough socket programs that I can decipher pretty much anything, so here's a working version of your code (with some pretty suboptimal parameters e.g. a buffer size of 1, but how else would you expect to catch a single ;?)
Server:
import socket
HOST = '127.0.0.1' # The server's hostname or IP address
PORT = 8192 # The port used by the server
BUFFER_SIZE = 1
def server_socket():
data = []
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST,PORT))
s.listen()
while 1: # Accept connections from multiple clients
print('Listening for client...')
conn, addr = s.accept()
print('Connection address:', addr)
while 1: # Accept multiple messages from each client
buffer = conn.recv(BUFFER_SIZE)
buffer = buffer.decode()
if buffer == ";":
conn.close()
print("Received all the data")
for x in data:
print(x)
break
elif buffer:
print("received data: ", buffer)
data.append(buffer)
else:
break
server_socket()
Client:
import socket
import json
HOST = '127.0.0.1' # The server's hostname or IP address
PORT = 8192 # The port used by the server
def json_message(direction):
local_ip = socket.gethostbyname(socket.gethostname())
data = {
'sender': local_ip,
'instruction': direction
}
json_data = json.dumps(data, sort_keys=False, indent=2)
print("data %s" % json_data)
send_message(json_data + ";")
return json_data
def send_message(data):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
s.sendall(data.encode())
data = s.recv(1024)
print('Received', repr(data))
json_message("SOME_DIRECTION")
Im need is limited quantity the connections, in listen is set s.listen(2), but I don't see any exception and I can created three new connections and more. Where is the mistake?
def func():
global addr
host = socket.gethostbyname(socket.gethostname())
port = 9000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(2)
while True:
conn, addr = s.accept()
if addr not in clients_addr:
addr.append([conn, addr])
current_addr = addr
thread = Thread(conn, current_addr)
thread.start()
Even with the REUSEADDR option, I still cannot reuse the same set of ports. It gives me a 98, "address already in use" error.
Is there a way to kill the first group of sockets before the second group, or fix this?
In the code below, I'm doing the exact same thing twice.
servers = []
port_list = [i for i in range(40007, 40107)]
for port in port_list:
ds = ('', port)
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(ds)
server.listen(1)
servers.append(server)
found,_,_ = select.select(servers, [], [])
found = found[0]
conn, addr = found.accept()
print 'Connected by', addr
data = conn.recv(1024)
print "received", data
conn.sendall("message!!")
conn.close()
#time.sleep(10) # even this doesn't work
port_list = [i for i in range(40007, 40107)]
for port in port_list:
ds = ('', port)
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(ds)
server.listen(1)
servers.append(server)
found,_,_ = select.select(servers, [], [])
found = found[0]
conn, addr = found.accept()
print 'Connected by', addr
data = conn.recv(1024)
print "received", data
conn.sendall("message!!")
You need to close your server sockets after you're done with them. SO_REUSEADDR doesn't let you use the address of an open socket, only one that has been recently closed but is still lingering in the TIME_WAIT state.
Try something like this -- SO_REUSEPORT vs SO_REUSEADDR and you were appending into the same server list. Does it work for you ?
#!/usr/bin/env python
import os
import sys
import socket
import select
while True:
servers = []
port_list = [i for i in range(40007, 40107)]
for port in port_list:
ds = ('', port)
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
server.bind(ds)
server.listen(1)
servers.append(server)
f,_,_ = select.select(servers, [], [])
for found in f:
conn, addr = found.accept()
print 'Connected by', addr
data = conn.recv(1024)
print "received", data
conn.sendall("message!!\n")
conn.close()
#time.sleep(10) # even this doesn't work
servers = []
port_list = [i for i in range(40007, 40107)]
for port in port_list:
ds = ('', port)
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
server.bind(ds)
server.listen(1)
servers.append(server)
f,_,_ = select.select(servers, [], [])
for found in f:
conn, addr = found.accept()
print 'Connected by -- BB', addr
data = conn.recv(1024)
print "received --- BB\n", data
conn.sendall("message!!----BB\n")
conn.close()
this is my server:
import socket
for port in range(33,128):
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind(('0.0.0.0', port))
while True:
(client_name, client_adress) = server_socket.recvfrom(1024)
print chr(port)
server_socket.close()
this is my client:
import socket
message = raw_input("Enter a message: ")
for letter in message:
my_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
while True:
my_socket.sendto("", ('127.0.0.1', ord(letter)))
(data, remote_adress) = my_socket.recvfrom(1024)
my_socket.close()
print 'The server sent: ' + data
I'm not very good in python, but I think you should save your sockets to list inside for and then use select function in infinite loop outside for
import socket
import select
sockets = []
for port in range(33,128):
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind(('0.0.0.0', port))
sockets.append(server_socket)
empty = []
while True:
readable, writable, exceptional = select.select(sockets, empty, empty)
for s in readable:
(client_data, client_address) = s.recvfrom(1024)
print client_address, client_data
for s in sockets:
s.close()