I was trying to make a simple chat room using Sockets in python3. When I ran my server on my localhost and set up clients using multiple terminals, everything went fine. When I tried to connect to the server (which was hosted on my system) by another system connected to same LAN network, this error came out.
ConnectionResetError: [Errno 104] Connection reset by peer
When I tried to reconnect from second system again and again it gave me another error
BrokenPipeError: [Errno 32] Broken pipe
This is my server.py
from socket import AF_INET, SOCK_STREAM, socket
from threading import Thread
HOST = "192.168.157.206"
PORT = 3000
addresses = {}
clients = {}
def Connections():
while True:
client, addr = server.accept()
print("{} is connected!!".format(addr))
client.send(("Welcome to Chat Room. Type {quit} to exit. Enter your name: ").encode("utf-8"))
addresses[client] = addr
Thread(target = ClientConnection, args=(client, )).start()
def ClientConnection(client):
name = client.recv(BufferSize).decode("utf-8")
client.send(("Hello {}".format(name)).encode("utf-8"))
message = ("{} has joined the chat..").format(name)
Broadcast(message.encode("utf-8"))
clients[client] = name
while True:
msg = client.recv(BufferSize).decode("utf-8")
if msg != "quit":
Broadcast(msg.encode("utf-8"), name + ": ")
else:
message = ("{} has left the chat.").format(clients[client])
Broadcast(message.encode("utf-8"))
client.send(("Will see you soon..").encode("utf-8"))
del clients[client]
break
def Broadcast(msg, name = ""):
for sockets in clients:
sockets.send(name.encode("utf-8") + msg)
server = socket(family=AF_INET, type=SOCK_STREAM)
try:
server.bind((HOST, PORT))
except OSError:
print("Server Busy")
BufferSize = 1024
server.listen(5)
print("Waiting for Connections... ")
AcceptThread = Thread(target=Connections)
AcceptThread.start()
AcceptThread.join()
server.close()
This is my client.py
from socket import AF_INET, SOCK_STREAM, socket
from threading import Thread
HOST = input("Enter Host IP: ")
PORT = eval(input("Enter Port No: "))
BufferSize = 1024
def Recieve():
while True:
try:
msg = client.recv(BufferSize).decode("utf-8")
print(msg)
except OSError:
break
def Send():
while True:
msg = input()
if msg == "quit":
client.send(msg.encode("utf-8"))
client.close()
break
else:
client.send(msg.encode("utf-8"))
client = socket(family=AF_INET, type=SOCK_STREAM)
client.connect((HOST, PORT))
RecieveThread = Thread(target=Recieve).start()
SendThread = Thread(target=Send).start()
Please tell me where I went wrong. I went through this answer here. But I cannot figure out where to correct this in my code.
Thanks in advance.
Related
I'm a novice when it comes to networking, but for my distributed systems project I'm attempting to create a simple application that allows any computer on the same network with python to send messages to a server. I cannot get my computer and laptop to connect successfully, and I get a timeout error on the client side:
Here is my server code:
import socket
import select
HEADER_LENGTH = 10
IP = "127.0.0.1"
PORT = 1234
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((IP, PORT))
server_socket.listen()
sockets_list = [server_socket]
clients = {}
def receive_message(client_socket):
try:
message_header = client_socket.recv(HEADER_LENGTH)
if not len(message_header):
return False
message_length = int(message_header.decode("utf-8").strip())
return {"header": message_header, "data" : client_socket.recv(message_length)}
except:
return False
while True:
read_sockets, _, exception_sockets = select.select(sockets_list, [], sockets_list)
for notified_socket in read_sockets:
if notified_socket == server_socket:
client_socket, client_address = server_socket.accept()
user = receive_message(client_socket)
if user is False:
continue
sockets_list.append(client_socket)
clients[client_socket] = user
print(f"Accepted new connection from {client_address[0]}:{client_address[1]} username:{user['data'].decode('utf-8')}")
else:
message = receive_message(notified_socket)
if message is False:
print(f"Closed connection from {clients[notified_socket]['data'].decode('utf-8')}")
sockets_list.remove(notified_socket)
del clients[notified_socket]
continue
user = clients[notified_socket]
print(f"Received message from {user['data'].decode('utf-8')}: {message['data'].decode('utf-8')}")
for client_socket in clients:
if client_socket != notified_socket:
client_socket.send(user['header'] + user['data'] + message['header'] + message['data'])
for notified_socket in exception_sockets:
sockets_list.remove(notified_socket)
del clients[notified_socket]
Here is my client code
import socket
import select
import errno
import sys
HEADER_LENGTH = 10
IP = "127.0.0.1"
PORT = 1234
my_username = input("Username: ")
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((IP, PORT))
client_socket.setblocking(False)
username = my_username.encode("utf-8")
username_header = f"{len(username):<{HEADER_LENGTH}}".encode("utf-8")
client_socket.send(username_header + username)
while True:
message = input(f"{my_username} > ")
if message:
message = message.encode("utf-8")
message_header = f"{len(message):<{HEADER_LENGTH}}".encode("utf-8")
client_socket.send(message_header + message)
try:
while True:
#receive things
username_header = client_socket.recv(HEADER_LENGTH)
if not len(username_header):
print("connection closed by the server")
sys.exit()
username_length = int(username_header.decode("utf-8").strip())
username = client_socket.recv(username_length).decode("utf-8")
message_header = client_socket.recv(HEADER_LENGTH)
message_length = int(message_header.decode("utf-8").strip())
message = client_socket.recv(message_length).decode("utf-8")
print(f"{username} > {message}")
except IOError as e:
if e.errno != errno.EAGAIN and e.errno != errno.EWOULDBLOCK:
print('Reading error', str(e))
sys.exit()
continue
except Exception as e:
print('General error', str(e))
sys.exit()
On the same machine, it works as expected since I'm using the hostname for both the server and client, but obviously, it will not work on separate devices.
How may I change this code so that I can get my laptop to act as a client, and my computer to act as a server? I only need to connect to devices on the same network. Thank you for any answers.
I found the solution myself, I just had to set the 'IP' in client to that of the server local IP, and lastly run both in IDLE so I would get the prompt to bypass the firewall, as I was running cmd previously and was not getting the option to bypass.
I'm trying to create an online code to a game I'm making. Obviously, running this code gives an error. The error is [WinError 10053] An established connection was aborted by the software in your host machine.
Here's my code:
SERVER
from _thread import *
import sys
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
server = 'localhost'
port = 5555
server_ip = socket.gethostbyname(server)
try:
s.bind((server, port))
except socket.error as e:
print(str(e))
s.listen(2)
print("Currently waiting for other users...")
currentId = "0"
pos = ["0:50,50", "1:100,100"]
def threaded_client(conn):
global currentId, pos
conn.send(str.encode(currentId))
currentId = "1"
reply = ''
while True:
try:
data = conn.recv(2048)
reply = data.decode('utf-8')
if not data:
conn.send(str.encode("Goodbye"))
break
else:
print("Recieved: " + reply)
arr = reply.split(":")
id = int(arr[0])
pos[id] = reply
if id == 0: nid = 1
if id == 1: nid = 0
reply = pos[nid][:]
print("Sending: " + reply)
conn.sendall(str.encode(reply))
except:
break
print("Connection Closed")
conn.close()
while True:
conn, addr = s.accept()
start_new_thread(threaded_client, (conn,))
CLIENT
import time
class Network:
def __init__(self):
randomvar = "."
while True:
try:
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.host = "localhost" # For this to work on your machine this must be equal to the ipv4 address of the machine running the server
# You can find this address by typing ipconfig in CMD and copying the ipv4 address. Again this must be the servers
# ipv4 address. This feild will be the same for all your clients.
self.port = 5555
self.addr = (self.host, self.port)
self.id = self.connect()
break
except ConnectionRefusedError:
if randomvar != "Waiting for server...":
print("Waiting for server...")
randomvar = "Waiting for server..."
def getNumber(self):
pass
def connect(self):
self.client.connect(self.addr)
return self.client.recv(2048).decode()
def send(self, data):
"""
:param data: str
:return: str
"""
try:
self.client.send(str.encode(data))
reply = self.client.recv(2048).decode()
return reply
except socket.error as e:
return str(e)
n = Network()
print(n.send("Host"))
print(n.send("hello"))
On the server, the only things it receives Host, but not hello. That's where I get the error, but It won't tell me which line it is.
Any help?
You are ignoring the exception. Instead, print it out to get an idea of what is wrong:
Traceback (most recent call last):
File "D:\temp\python\server.py", line 39, in threaded_client
id = int(arr[0])
ValueError: invalid literal for int() with base 10: 'Host'
This leads to this line:
id = int(arr[0])
It looks like the server is expecting the messages to be in the form of id:msg but the client is not sending that. It is just sending the message without an id. You can check this in the server.
arr = reply.split(":")
if len(arr) != 2 or !arr[0].isdigit():
# Handle error....
When closing the connection, you are likely forgetting to close both sides.
I was able to modify your code to fit the scenario from this post which explains the root cause of [WinError 10053] An established connection was aborted by the software in your host machine, which lies in the WSAECONNABORTED error from WinSock, the windows sockets api
I made a more detailed answer about this on this SO post.
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!
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()