How to connect to Python socket server from another network - python

I'm new to socket programming and I'm trying to make a server with socket module. When working on a local network it works perfectly fine, but the problem comes when I'm trying to run it and connect from two different networks. I've tried many things that I saw on SO and the internet in general.
Server code:
import socket
import threading
SERVER = socket.gethostbyname('')
PORT = 12345
ADDR = (SERVER, PORT)
HEADER = 64
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = '!DISCONNECT'
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
def handle_client(conn, addr):
print(f'[NEW CONNECTION] {addr} connected.')
print(f'[ACTIVE CONNECTIONS] {threading.active_count() - 1}')
connected = True
while connected:
msg_lenght = conn.recv(HEADER).decode(FORMAT)
if msg_lenght:
msg_lenght = int(msg_lenght)
msg = conn.recv(msg_lenght).decode(FORMAT)
if msg == DISCONNECT_MESSAGE:
connected = False
print(f'[MESSAGE RECIEVED] FROM: {addr}; Message: {msg}')
conn.send('Message 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'IP Address: {SERVER}')
print('[STARTING] Server is starting...')
start()
Client code:
import socket
SERVER = input('IP Address: ')
PORT = 5050
ADDR = (SERVER, PORT)
HEADER = 64
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = '!DISCONNECT'
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(ADDR)
def send(msg):
message = msg.encode(FORMAT)
msg_lenght = len(message)
send_lenght = str(msg_lenght).encode(FORMAT)
send_lenght += b' ' * (HEADER - len(send_lenght))
client.send(send_lenght)
client.send(message)
while True:
user_Input = input('Message: ')
send(user_Input)
if user_Input == DISCONNECT_MESSAGE:
break
I tried making "rules" on the firewall that should make my port public or something. I have also tried different addresses because I was not sure which one to use.
Thanks in advance!

Related

Things to consider while failproofing socket communciation

I have a simple client/server socket program written in python. So far I think I have managed to deal with two types of certain socket errors.
server is not alive when the client is open (Connectionrejected)
server shuts down while the client is open (Connectionreset)
I am wondering what other errors I should be accounting for. When the client sends a message and the server is closed before the send happens, the client waits until it can reconnect and sends the message however I am not sure if that covers all the cases where the message can be lost or not transmitted completely.
server.py
import socket
import threading
HEADER = 8
PORT = 5050
SERVER = "127.0.0.1" #socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "exit"
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(ADDR)
def close():
server.shutdown(socket.SHUT_RDWR)
server.close()
print ("closed")
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}] {msg}")
conn.send("Barcode received".encode(FORMAT))
conn.shutdown(socket.SHUT_RDWR)
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.active_count() - 1}")
print("[STARTING] server is starting...")
start()
client.py
import socket
import datetime
import time
HEADER = 8
PORT = 5050
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "exit"
SERVER = "127.0.0.1"
ADDR = (SERVER, PORT)
def check_connection(ADDR):
print("Trying to connect to the server...")
connected = False
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
while not connected:
try:
client.connect(ADDR)
except socket.error as error:
connected = False
time.sleep(0.01)
print("Can't connect.Retrying...")
#print(connected)
else:
connected = True
print("Connected to the server")
return client
def send(msg,client,ADDR):
message = msg.encode(FORMAT)
msg_length = len(message)
send_length = str(msg_length).encode(FORMAT)
send_length += b' ' * (HEADER - len(send_length))
sending = True
while sending :
try:
cl_ls[0].send(send_length)
cl_ls[0].send(message)
print(cl_ls[0].recv(2048).decode(FORMAT))
sending = False
except socket.error as error:
cl_ls[0] = check_connection(ADDR)
cl_ls[0].send(send_length)
cl_ls[0].send(message)
sending = False
print(cl_ls[0].recv(2048).decode(FORMAT))
cl_ls = ["client"]
client = check_connection(ADDR)
cl_ls[0] = client
accept_more_barcodes = True
while accept_more_barcodes:
input_value = input("Type 'exit' to close input box ")
today = datetime.datetime.now()
date_time = today.strftime("%m/%d/%Y, %H:%M:%S")
input_value += ' *** ' + date_time
if (input_value).startswith("exit"):
accept_more_barcodes = False
else:
with open("barcodes.txt", "a") as f:
f.write(input_value + "\n")
send(input_value,cl_ls[0],ADDR)

how can I send a message to all of my clients connect to my server (socket)

My code is below and I just can't seem to figure out how to send messages to my clients at once
Even when I try asking for help or anything like that they say Store each client and idk how to do that. also I did try it and look it up I did it but I want it to update instantly like discord
import socket
import threading
HEADER = 64
PORT = 5050
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!stop"
NAME_MESSAGE = "!name"
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
def handle_client(client, addr):
print(f'[INFO] {addr} connected.')
while True:
msg_length = client.recv(HEADER).decode(FORMAT)
if not msg_length:
msg_length = int(msg_length)
msg = client.recv(msg_length).decode(FORMAT)
if msg == DISCONNECT_MESSAGE:
print(f'[DISCONNECT] {addr} Disconnected')
break
elif msg == NAME_MESSAGE:
name_length = client.recv(HEADER).decode(FORMAT)
if name_length:
name_length = int(name_length)
name = client.recv(name_length).decode(FORMAT)
addr = name
else:
<Idk what to put here>
else:
break
def start():
server.listen()
print(f'[INFO] Server is listening on {SERVER}')
while True:
conn, addr = server.accept()
thread = threading.Thread(target=handle_client, args=(conn, addr))
thread.start()
print(f'\n[INFO] Active connections: {threading.activeCount() - 1}')
print('[INFO] Server is starting...')
start()

Python socket chat server only listens to one client

Hi I am working on a self made chat server using python and sockets. I was trying to finish the entire thing without a tutorial but I have been stuck on this for about 4 days now and decided to get some help.
I have gotten far enough that the server can have clients connect to it, it can store there data, and receive and send out messages, My problem is that after connecting two clients and sending about 4 messages the server stops receiving messages from one of the two clients. But the client that can no longer send messages can still see incoming messages from the other client
Here is the code for my server
import socket
import threading
HEADER = 100
PORT = 1234
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
FORMAT = "utf-8"
DISCONNECT_MESSAGE = "DISCONNECT"
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
#list of all connected clients
cl = []
#is run when i new client connects
def handle_client(conn, addr):
print(f"[NEW CONNECTION] {addr} connected.")
connected = True
while connected:
msg = conn.recv(2048).decode(FORMAT)
if msg == DISCONNECT_MESSAGE:
connected = False
for i in range(threading.activeCount() - 1):
print(" ")
conn = cl[i]
print(" ")
conn.send(msg.encode(FORMAT))
conn.close()
#scans for new clients
def start():
server.listen(5)
print(f"[LISTENING] Server is listening on {SERVER}")
while True:
conn, addr = server.accept()
client_con = threading.Thread(target=handle_client, args=(conn, addr))
client_con.start()
print(f"[ACTIVE CONNECTIONS] {threading.activeCount() - 1}")
print(" ")
#adds new client to clients list
cl.append(conn)
print("[STARTING] server is starting...")
start()
And here is the code for my client
import socket
import threading
HEADER = 100
PORT = 1234
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)
#get users name that is show befor message's
def get_info():
name = input("whats your name: ")
NAME = name
NAME = NAME + "-"
return NAME
#sends messags's to server
def send_msg():
NAME = get_info()
while True:
print(" ")
msg = input("type your message: ")
print(" ")
msg = NAME + " " + msg
message = msg.encode(FORMAT)
client.send(message)
#recives messages from server
def recs():
while True:
print(" ")
msg_rcv = client.recv(5000)
print(msg_rcv.decode(FORMAT))
print(" ")
send = threading.Thread(target=send_msg)
rec = threading.Thread(target=recs)
rec.start()
send.start()
Thank you for reading and any help is very apricated have a great day! <:
Well turns out i finally found my issues after making a flow chart to help me visualize where an issue could occur.
the issue was in my server and had to do with the con variable in this strip of code
msg = conn.recv(2048).decode(FORMAT)
if msg == DISCONNECT_MESSAGE:
connected = False
for i in range(threading.activeCount() - 1):
print(" ")
conn = cl[i]
print(" ")
conns.sendall(msg.encode(FORMAT))
i just needed to use a diffrent var for sending the message so here is the working server code
import socket
import threading
HEADER = 100
PORT = 1234
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
FORMAT = "utf-8"
DISCONNECT_MESSAGE = "DISCONNECT"
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
#list of all connected clients
cl = []
#is run when i new client connects
def handle_client(conn, addr):
print(f"[NEW CONNECTION] {addr} connected.")
connected = True
while connected:
msg = conn.recv(2048).decode(FORMAT)
print(f"[MSG IS]--> {msg}")
if msg == DISCONNECT_MESSAGE:
connected = False
for i in range(threading.activeCount() - 1):
print(" ")
conns = cl[i]
print(" ")
conns.sendall(msg.encode(FORMAT))
#conn.close()
#scans for new clients
def start():
server.listen(5)
print(f"[LISTENING] Server is listening on {SERVER}")
while True:
conn, addr = server.accept()
client_con = threading.Thread(target=handle_client, args=(conn, addr))
client_con.start()
print(f"[ACTIVE CONNECTIONS] {threading.activeCount() - 1}")
print(" ")
#adds new client to clients list
cl.append(conn)
print("[STARTING] server is starting...")
start()
#we need to find a way to send a message from a client to all other clients!
all i had to do was change one of the conn to conns so it would not mix things up!

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.

Problem with pickle.loads() - ran out of input

I'm trying to make a small multiplayer game and thus need to send objects. Have created server and client and everything is working for sending bytes e.g. (str("").encode(utf-8)).
But when I tried to use pickle I've started bumping into issues. Have I made any mistakes below?
Server.py:
import socket
import threading
import pickle
HEADER = 8 #Contains info about incoming msg SIZE! first 8 bytes contains size
FORMAT = "utf-8"
PORT = 5558
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
DISCONNECT_MSG = "!Disconnect"
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(ADDR)
def handle_client(client_socket, client_addr):
print(f"[NEW CONNECTION] {client_addr} connected!")
while True:
try:
msg = pickle.loads(client_socket.recv(2048))
print(f"[RECEIVED] {client_addr} - {msg}")
if msg == DISCONNECT_MSG:
print(f"[DISCONNECTED] client {client_addr} has disconnected")
client_socket.close()
return False
except socket.error as e:
print(e)
def start_server(server):
server.listen()
print("[STARTED] server is online!")
while True:
client_socket, client_addr = server.accept()
thread = threading.Thread(target=handle_client, args=(client_socket, client_addr))
thread.start()
print(f"[ACTIVE CONNECTIONS] {threading.activeCount() - 1}")
print("[STARTING] server is starting...")
start_server(server_socket)
Client.py
import socket
import pickle
HEADER = 8
FORMAT = "utf-8"
PORT = 5558
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
DISCONNECT_MSG = "!Disconnect"
class Client:
def __init__(self):
self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def connect_to_server(self, server_address):
"""
:param server_address: tuple(IP, PORT)
:return:
"""
self.get_client_socket().connect(server_address)
def get_client_socket(self):
return self.client_socket
def send_object(self, object):
msg = pickle.dumps(object)
self.get_client_socket().sendall(msg)
client = Client()
client.connect_to_server(ADDR)
d = "1"
client.send_object(d)
#client.send_object(DISCONNECT_MSG)
I've also tried to put while loop into send_object() but then after couple of successful receivements I get:
msg = pickle.loads(client_socket.recv(2048))
_pickle.UnpicklingError: invalid load key, '\x00'.
After some research it appears that before trying to unpickle an object you first need to check if received message is not None. Because server is constantly trying to receive message from client, but that is another issue.
Code modification in server.py:
def handle_client(client_socket, client_addr):
print(f"[NEW CONNECTION] {client_addr} connected!")
while True:
try:
msg = client_socket.recv(2048)
if msg:
new_msg = pickle.loads(msg[HEADER:])
print(f"[RECEIVED] {client_addr} - {new_msg}")
if msg == DISCONNECT_MSG:
print(f"[DISCONNECTED] client {client_addr} has disconnected")
client_socket.close()
return False
except socket.error as e:
print(e)
Note -> Until DISCONNECT message is not sent from client it will use much processor time (issue mentioned above)

Categories