I am programming a decentralised script to track the IPs of other computers running the script, to explore decentralisation. This script isolates the problem. The code consists of 2 scripts, one main program which sends its IP to an IP provided if one is provided, and a listener program which is run as a subscript and listens for data and pipes that data back to the main program. The main script appears to be working, the data is sent over the network, but the listener does not receive it.
This is the main script
import socket
from subprocess import Popen, PIPE
from time import sleep
def getIP():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
s.connect(('8.8.8.4', 1))
IP = s.getsockname()[0]
except Exception:
IP = '127.0.0.1'
finally:
s.close()
return IP
def sendfyi(target, ownIP):
toSend = 'fyi' + ':' + ownIP
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((target, 50000))
s.send(toSend.encode())
s.close()
print('sent fyi')
otherIPs = []
ownIP = getIP()
targetIP = input('enter ip or 0: ')
if targetIP != '0':
otherIPs.append(targetIP)
sendfyi(targetIP, ownIP)
listener = Popen(['python3', 'testlistener.py'], stdout=PIPE, stderr=PIPE)
i = 0
while i == 0:
sleep(1)
listenerPipe = listener.stdout.readline()
print(listenerPipe)
This is the sub process:
import socket
def getIP():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
# doesn't even have to be reachable
s.connect(('8.8.8.4', 1))
IP = s.getsockname()[0]
except Exception:
IP = '127.0.0.1'
finally:
s.close()
return IP
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((getIP(), 50000))
i = 1
while i == 1:
s.listen(1)
conn, addr = s.accept()
print('conected', flush=True)
data = conn.recv(1024)
print('data receved', flush=True)
out = data.decode()
print('data decoded', flush=True)
print(out, flush=True)
conn.close()
Incorect bind statement
bind(('', 50000))
Related
OSError: [WinError 10057] A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied.
I am getting the above error..My server and client can send and receive their first messages but I get this error if I try to send more than one message.
My Server Code is here
import socket
import threading
import time
from tkinter import *
#functions
def t_recv():
r = threading.Thread(target=recv)
r.start()
def recv():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as listensocket:
port = 5354
maxconnections = 9
ip = socket.gethostbyname(socket.gethostname())
print(ip)
server = (ip, port)
FORMAT = 'utf-8'
listensocket.bind((server))
listensocket.listen(maxconnections)
(clientsocket, address) = listensocket.accept()
msg = f'\[ALERT\] {address} has joined the chat.'
lstbox.insert(0, msg)
while True:
sendermessage = clientsocket.recv(1024).decode(FORMAT)
if not sendermessage == "":
time.sleep(3)
lstbox.insert(0, 'Client: ' +sendermessage)
def t_sendmsg():
s = threading.Thread(target=sendmsg)
s.start()
at = 0
def sendmsg():
global at
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as g:
hostname = 'Lenovo-PC'
port = 5986
if at==0:
g.connect((hostname, port))
msg = messagebox.get()
lstbox.insert(0, 'You: ' +msg)
g.send(msg.encode())
at += 1
else:
msg = messagebox.get()
lstbox.insert(0, 'You: ' +msg)
g.send(msg.encode())
And my client code is same with minor difference
import socket
import time
import threading
from tkinter import *
#functions
def t_recv():
r = threading.Thread(target=recv)
r.start()
def recv():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as listensocket:
port = 5986
maxconnections = 9
ip = socket.gethostname()
print(ip)
FORMAT = 'utf-8'
host = 'MY_IP' # My actual ip is there in the code
listensocket.bind((host, port))
listensocket.listen(maxconnections)
(clientsocket, address) = listensocket.accept()
while True:
sendermessage = clientsocket.recv(1024).decode(FORMAT)
if not sendermessage == "":
time.sleep(3)
lstbox.insert(0, 'Server: ' +sendermessage)
def t_sendmsg():
s = threading.Thread(target=sendmsg)
s.start()
at = 0
def sendmsg():
global at
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as g:
hostname = 'Lenovo-PC'
port = 5354
if at==0:
g.connect((hostname, port))
msg = messagebox.get()
lstbox.insert(0, 'You: ' +msg)
g.send(msg.encode())
at += 1
else:
msg = messagebox.get()
lstbox.insert(0, 'You: ' +msg)
g.send(msg.encode())
Please let me know what changes are required to be made in order to make it run for every message.
I tried to put
g.connect((hostname, port))
the above line in the loop so that it will connect every time loop iterates. But it did not help.
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as g:
...
if at==0:
g.connect((hostname, port))
...
g.send(msg.encode())
at += 1
else:
...
g.send(msg.encode())
In the if at==0 condition it connects to the server, in the else part not. But is still trying to send something on the not connected socket.
Why does my Python P2P client works over LAN but not the Internet and how can I fix this!
I would like to make a p2p messenger and I just don't know why the p2p functionality with UDP Hole Punching is not working. Please help!
Server:
This server holds peers ips and ports for the client.
The ping function pings the peers to check if they are still alive.
'''
import threading
import socket
import time
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(("IP_ADDRESS", 8081))
addrs = []
print('Server started...')
def ping(addr):
try:
sock.sendto(b'ping', addr)
sock.settimeout(1)
data, addr = sock.recvfrom(1024)
sock.settimeout(None)
return True
except Exception as ex:
sock.settimeout(None)
return False
while True:
data, addr = sock.recvfrom(1024)
print(addr)
sock.sendto((addr[0]+' '+str(addr[1])).encode(), addr)
for a in addrs:
p = ping(a)
print(p, a)
if p:
sock.sendto((a[0]+' '+str(a[1])).encode(), addr)
addrs.append(addr)
sock.sendto(b'DONE', addr)
'''
Client:
import threading
import socket
import time
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.addrs = []
self.chat_logs = ''
self.peers = ''
self.self_data = ('0.0.0.0', 0)
def recv_thread(self):
while True:
try:
data, addr = self.sock.recvfrom(1024)
if data == b'ping':
self.sock.sendto(b'pong', addr)
else:
data = data.decode()
new_user = True
for a in self.addrs:
if a == addr:
new_user = False
if new_user == False:
self.chat_logs += addr[0]+':'+str(addr[1])+' - '+data+'\n'
else:
self.chat_logs += addr[0]+':'+str(addr[1])+' joined the p2p network... \n'
self.addrs.append(addr)
except Exception as ex:
print(ex)
def send_msg(self):
message = self.messageBox.text()
if len(message) > 0:
self.chat_logs += 'You - '+message+'\n'
self.chatBox.setPlainText(self.chat_logs)
for a in self.addrs:
try:
self.sock.sendto(message.encode(), a)
except:
self.addrs.remove(a)
def get_peers(self, host):
host = host.split(':')
host = (host[0], int(host[1]))
self.sock.sendto(b'PEERS', host)
self.self_data, addr = self.sock.recvfrom(512)
self.self_data = self.self_data.decode().split()
self.self_data = (self.self_data[0], int(self.self_data[1]))
while True:
data, addr = self.sock.recvfrom(512)
if data == b'DONE':
break
else:
data = data.decode().split()
self.addrs.append((data[0], int(data[1])))
print(self.addrs)
for a in self.addrs:
try:
self.sock.sendto(b'join', a)
except:
self.addrs.remove(a)
t = threading.Thread(target=self.recv_thread)
t.start()
def connect_to_pears_network(self):
dlg = CustomDialog()
if dlg.exec():
text = dlg.message.text()
if len(text) > 6:
self.get_peers(text)
else:
pass
I hope I did this post right this is my first time making a post.
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 server and I need it to receive multiple connections and messages.
The server receives new connections without problems but it doesn't get multiple messages from one connection.
import socket
import select
HEADER_LENGTH = 1024
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
server_socket.bind((HOST, PORT))
except socket.error as e:
print(str(e))
print("Server is connected")
server_socket.listen(5)
sockets_list = [server_socket]
clients = {}
print("Server is listening")
def receive_message(conn):
try:
data = conn.recv(HEADER_LENGTH)
if not len(data):
return False
strdata = data.decode('utf-8')
print(strdata)
return strdata
except Exception as e:
print(e)
return False
def handle_client():
conn, addr = server_socket.accept()
print(f"Accepted new connection from {addr[0]}:{addr[1]}")
sockets_list.append(conn)
while True:
read_sockets, _, exception_sockets = select.select(sockets_list, [], [], 0)
for i in read_sockets:
if i == server_socket:
handle_client()
else:
print("received message")
message = receive_message(i)
if message is False:
sockets_list.remove(i)
try:
del clients[i]
except KeyError:
pass
continue
if message is not None:
clients[i] = message
if message is not None:
for client_socket in clients:
if client_socket != i:
client_socket.send(str.encode(message))
print("sent to all players")
What happens it that after receiving the first message, the server stops receiving messages from that connection.
And of course there is a lot more code but I showed you the relevant code.
I'll be very happy if someone helps me with that, I've surfed the web so much but haven't seen a solution for my problem.
updates:
I've tried to put socket.close() on my client side(written in Java) and then server gets maximum 2 messages and the problems with it are:
1. The server gets maximum 2 messages.
2. the connection changes(I need that the connection will stay static if possible)
try this code block
#-*- coding:utf-8 -*-
import socket
import sys
#get machine ip address
server_ip = socket.gethostbyname(socket.gethostname())
#create socket object
s = socket.socket()
#define port number
port = 6666
#bind ip and port to server
s.bind((server_ip,port))
#now waiting for clinet to connect
s.listen(5)
print("Enter this ip to connect your clinet")
print(server_ip)
clients = []
flag = True
recv_data = ""
if not clients:
c, addr = s.accept()
print("this is c ",c," this is Addr ",addr)
clients.append(c)
recv_data = c.recv(1024)
print(recv_data.decode("utf-8"))
if flag == True:
while recv_data.decode("utf-8") != "EX":
recv_data = c.recv(1024)
recv_data.decode("utf-8")
if recv_data.decode("utf-8") == "EX":
s.close()
print("check false")
break
s.close()
I am making server-client communication in python using sockets and threading module. I connect client to server, send some data, receive some data, but the problem is, I can send only two messages. After those, the server is not reciving my packets. Can someone tell me what's wrong? Thanks in advance.
Server.py:
import socket
from threading import Thread
class Server:
def __init__(self):
self.host = '127.0.0.1'
self.port = 9999
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind((self.host, self.port))
self.server.listen(5)
self.threads = []
self.listen_for_clients()
def listen_for_clients(self):
print('Listening...')
while True:
client, addr = self.server.accept()
print('Accepted Connection from: '+str(addr[0])+':'+str(addr[1]))
self.threads.append(Thread(target=self.handle_client, args=(client, addr)))
for thread in self.threads:
thread.start()
def handle_client(self, client_socket, address):
client_socket.send('Welcome to server'.encode())
size = 1024
while True:
message = client_socket.recv(size)
if message.decode() == 'q^':
print('Received request for exit from: '+str(address[0])+':'+str(address[1]))
break
else:
print('Received: '+message.decode()+' from: '+str(address[0])+':'+str(address[1]))
client_socket.send('Received request for exit. Deleted from server threads'.encode())
client_socket.close()
if __name__=="__main__":
main = Server()
Client.py
import socket
import sys, time
def main():
target_host = '127.0.0.1'
target_port = 9999
try:
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
print('Could not create a socket')
time.sleep(1)
sys.exit()
try:
client.connect((target_host, target_port))
except socket.error:
print('Could not connect to server')
time.sleep(1)
sys.exit()
while True:
data = input()
client.send(data.encode())
message = client.recv(4096)
print('[+] Received: '+ message.decode())
main()
You have to send exit message 'q^' to client too to close client.
Warning:
Using Unicode as encoding for string is not recommended in socket. A partial Unicode character may be received in server/client resulting in UnicodeDecodeError being raised.
Code for server using threads is:
server.py:
import socket
from threading import Thread
class Server:
def __init__(self, host, port):
self.host = host
self.port = port
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind((self.host, self.port))
self.server.listen(5)
def listen_for_clients(self):
print('Listening...')
while True:
client, addr = self.server.accept()
print(
'Accepted Connection from: ' + str(addr[0]) + ':' + str(addr[1])
)
Thread(target=self.handle_client, args=(client, addr)).start()
def handle_client(self, client_socket, address):
size = 1024
while True:
try:
data = client_socket.recv(size)
if 'q^' in data.decode():
print('Received request for exit from: ' + str(
address[0]) + ':' + str(address[1]))
break
else:
# send getting after receiving from client
client_socket.sendall('Welcome to server'.encode())
print('Received: ' + data.decode() + ' from: ' + str(
address[0]) + ':' + str(address[1]))
except socket.error:
client_socket.close()
return False
client_socket.sendall(
'Received request for exit. Deleted from server threads'.encode()
)
# send quit message to client too
client_socket.sendall(
'q^'.encode()
)
client_socket.close()
if __name__ == "__main__":
host = '127.0.0.1'
port = 9999
main = Server(host, port)
# start listening for clients
main.listen_for_clients()
client.py:
import socket
import sys, time
def main():
target_host = '127.0.0.1'
target_port = 9999
try:
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
print('Could not create a socket')
time.sleep(1)
sys.exit()
try:
client.connect((target_host, target_port))
except socket.error:
print('Could not connect to server')
time.sleep(1)
sys.exit()
online = True
while online:
data = input()
client.sendall(data.encode())
while True:
message = client.recv(4096)
if 'q^' in message.decode():
client.close()
online = False
break
print('[+] Received: ' + message.decode())
break # stop receiving
# start client
main()