Having trouble connecting to a local server in Python - python

I'm currently following this tutorial on how to make a multiplayer game using python: https://www.youtube.com/watch?v=McoDjOCb2Zo
I'm currently trying to connect to a server file with a network file. Running the server file prints out the correct piece of information but once I try connecting to it with the network file nothing happens.
Here is my server code. When it runs it prints out "Waiting for a connection, Server started
(I have removed my IP address, but I know that I have the right one in for when I run my code)
import socket
from _thread import *
server = "***.***.*.**"
port = 5555
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.bind((server, port))
except socket.error as e:
str(e)
s.listen(2)
print("Waitng for a connection, Server Started")
def threaded_client(conn):
conn.send(str.encode("Connected"))
reply = ""
while True:
try:
data = conn.recieve(2048)
reply = data.decode("utf-8")
if not data:
print("Disconnected")
break
else:
print("Received", reply)
print("Sending: ", reply)
conn.sendall(str.encode(reply))
except:
break
print("Lost Connection")
conn.close()
while True:
conn, addr = s.accept()
print("Conneced to: ", addr)
start_new_thread(threaded_client, (conn,))
And here is the code for my network
import socket
class Network:
def __init__(self):
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server = "***.***.*.**"
self.port = 5555
self.addr = (self.server, self.port)
self.id = self.connect()
print(self.id)
def connect(self):
try:
self.client.connect(self.addr)
return self.client.recv(2048).decode()
except:
pass
n = Network()
When I run this code after initializing the server, it is supposed to print out "Connected"

Related

Socket only accepts one Connection

My Python socket chat with multithreading only accepts one connection. If I try to connect a second client it doesn't work. On the client side it seems like everything is okay but if i try to send a second message from client 2 the message doesn't arrive.
import socket
import threading
class TxtSocket:
def __init__(self, host="127.0.0.1" , port=5555):
self.host = host
self.port = port
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.s.bind((self.host, self.port))
print("Socket was created")
def server(self):
self.s.listen()
print("Server is listening")
conn, addr = self.s.accept()
print(f"{addr} is now connected.")
while True:
data = conn.recv(1024).decode("utf8")
print(data)
if not data:
break
if __name__ == "__main__":
txtsocket = TxtSocket()
for i in range(0, 26):
t = threading.Thread(target=txtsocket.server())
t.start()
# Client
import socket
def Text():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("127.0.0.1", 5555))
print("Connected")
while True:
message = input("Deine Nachricht: ")
message = message.encode("utf8")
s.send(message)
Text()
Need couple mods to the server to handle multiple clients.
Need main loop to keep accepting new connections and forking off the processing to a thread
Create a new thread to handle client connection when socket gets a new connection.
The following server code works with multiple running clients as specified above.
# server
import socket
import threading
class TxtSocket:
def __init__(self, host="127.0.0.1", port=5555):
self.host = host
self.port = port
self.thread = 0
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.s.bind((self.host, self.port))
print("Socket was created")
def handle(self, conn, addr):
self.thread += 1
print(f"Thread-{self.thread} {addr} is now connected")
while True:
data = conn.recv(1024)
if not data:
break
print(data.decode("utf8"))
conn.close()
def server(self):
# specify the number of unaccepted connections that the server
# will allow before refusing new connections.
self.s.listen(5)
print(f'Server listening on tcp:{self.host}:{self.port}')
while True:
conn, addr = self.s.accept()
# create new thread to handle the client connection
t = threading.Thread(target=self.handle, args=(conn, addr))
t.start()
if __name__ == "__main__":
txtsocket = TxtSocket()
txtsocket.server()
Note that Python has a SocketServer module that can make some of this easier with a TCPServer that does much of the work. See server example.
you can use thread for close other connections
import socket
from _thread import start_new_thread
server = socket...
first_connection = None
def check_con_isalive():
try:
while True:
first_connection.send(b"\0")
except Exception:
print("connnection was closed")
first_connection.close()
def thread_con(con):
global first_connection
if not first_connection:
first_connection = con
start_new_thread(check_con_isalive, ())
...
else:
print("blocking new connections")
con.close()
if __name__ == '__main__':
while True:
con, adr = server.accept()
start_new_thread(thread_con, (con, ))

Bytes get concatenated while trying to send data over sockets

I was trying to send some data over sockets, but I noticed that the bytes I send sometimes just get concatenated together.
Sorry if the wording is not great, but here’s some example code to reproduce this problem:
# SERVER CODE
import socket, pickle
from _thread import start_new_thread
IP = "0.0.0.0" # Address to bind to
PORT = 5555 # Arbitrary non-privileged port
DEFAULT_BYTES = 2048
total_connections_so_far = 0
def send(data, conn, pickle_data=True):
try:
if pickle_data:
data = pickle.dumps(data)
conn.sendall(data)
except Exception as e:
print("ERROR TRYING TO SEND DATA: ", e)
def threaded_client(conn, addr, user_id):
send(b"Hello there!", conn, False)
send(b"2nd message", conn, False)
send(b"Last message", conn, False)
conn.close()
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
# bind the socket to the host address and port
s.bind((IP, PORT))
print("Server started at: ", s.getsockname())
# listen for connections
s.listen()
print("Server has started. waiting for connections...")
while True:
conn, addr = s.accept()
print("[CONNECTED]: ", addr)
total_connections_so_far += 1 # increment the totoal connections
# start a thread for the new client
start_new_thread(threaded_client, (conn, addr, total_connections_so_far))
☝🏻 server.py
# CLIENT CODE
import socket, pickle
class Network:
def __init__(self):
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server = ""
self.port = 5555
self.addr = (
self.server,
self.port,
)
# function to connect to the server
def connect(self):
try:
self.client.connect(self.addr)
print("Connected!")
except Exception as e:
print("error while trying to connect:", e)
return False
# send some data to the server
def send(self, data, pickle_data=True):
try:
if pickle_data:
data = pickle.dumps(data)
self.client.sendall(data)
except Exception as e:
print("error while trying to send data:", e)
return False
# recieve some data from the server
def recv(self, buffer_size=2048):
try:
data = self.client.recv(buffer_size)
return data
except Exception as e:
print("error while recieving:", e)
client = Network()
client.connect()
data = client.recv()
print(data)
☝🏻 client.py
Try running the client code a few times and you’ll notice that sometimes, the data received is a concatenation of all 3 messages sent from the server.
So to get around this problem, I have been using time.sleep(1) after every time I send something, but this is obviously not a great idea.
I understand that this happens cuz ( correct me if I’m wrong ) I’m only sending tiny bits of data from the server, and expecting to receive 2048 bits on the client side, so the client waits for a while to try and receive the full amount of data.
But this is a pretty common problem and there must be a neat solution to it right?
I know I’m a total noob, but please help me!

No print message from socket server, reciving response from client sent message

I am setting up a client/server in Python with the ability to handle multiple clients.
Server code:
import socket
import threading
class Server:
def __init__(self):
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind(('127.0.0.1',1234 ))
print("Waiting for connection")
self.server.listen()
self.loop()
def thread_client(self, conn, addr):
print(addr, ' has connected')
while True:
data = conn.recv(1024)
conn.sendall(data)
def loop(self):
while True:
conn, addr = self.server.accept()
x = threading.Thread(target = self.thread_client, args=(conn, addr,))
x.start()
self.server.close()
s = Server()
Client code:
import socket
class Client:
def __init__(self):
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.connect()
def connect(self):
try:
self.client.connect(('127.0.0.1', 1234))
except:
print("Something went wrong...")
def send(self, data):
self.client.sendall(data)
return self.client.recv(1024)
c = Client()
print(c.send(b'Hello World'))
print(c.send(b'Hello World'))
When I run py server.py in one terminal this is all I get:
And from the client terminal this is how it looks:
My question is, why am I not recieving a simple print message from the initialization of the server? What does CLOSE_WAIT and FIN_WAIT_2 mean when I run netstat?
The server thread will loop forever until the socket times out resulting in WAIT states on the created sockets as shown in netstat command. Add a check in the server thread to check when data from the client is complete.
Socket Programming HOWTO states:
When a socket.recv returns 0 bytes, it means the other side has closed
(or is in the process of closing) the connection. You will not receive any
more data on this connection.
Server update:
import socket
import threading
class Server:
def __init__(self):
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind(('127.0.0.1', 1234))
print("Waiting for connection")
self.server.listen()
self.loop()
def loop(self):
while True:
conn, addr = self.server.accept()
x = threading.Thread(target=Server.thread_client, args=(conn, addr,))
x.start()
self.server.close()
#staticmethod
def thread_client(conn, addr):
print(addr, ' has connected')
while True:
data = conn.recv(1024)
if len(data) == 0:
break
print("recv:", data)
conn.sendall(data)
conn.close()
s = Server()
For the client, close the socket connect when done.
Client update:
c = Client()
print(c.send(b'Hello World'))
print(c.send(b'Hello World'))
c.client.close() # added

Cannot run multiple files when connected to Server in VSCode Python

I am trying to test connections to a server from a network. I have 2 seperate files; server.py and network.py.
My server.py works as it says "Server Started" but when I try to run network.py to connect to the server, it does not let me run it. I am doing this in VSCode so I don't know if its a software bug.
I have provided the server.py code and network.py code (They are in the same workspace and directory) and for privacy I have hidden my IP address
Server.py:
import socket
from _thread import *
import sys
server = "XXXXXX" # server address on LAN
port = 5555 # 5555 is an open safe port for use
socket_x = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# .AF_INET allows sokcet to communicate with addresses
# SOCK_STREAM IS USED BY TCP SERVER WHICH ALLOWS DEVICES TO TRANSMIT DATA TO ONE ANOTHER
try: # check for socket errors
socket_x.bind((server, port)) # creating server
except socket.error as e:
str(e)
socket_x.listen(2) # allows for connections (2 people can connect)
print("Waiting for Connection, Test Server Started")
def threaded_client(conn):
conn.send(str.encode("Connected"))
reply = ""
while True:
try:
data = conn.recv(2048)
reply = data.decode("utf-8")
if not data:
print("Disconnected")
break
else: # if there is data
print("Recieved: ", reply)
print("Sending: ", reply)
conn.sendall(str.encode(reply))
except:
break
print("Lost connection")
conn.close()
while True: # continuosly looking for connections
conn, address = socket_x.accept() # accept any incoming connections and store into variables
print("Connected to:", address)
# start_new_thread(threaded_client, (conn, ))
start_new_thread(threaded_client, (conn, ))
Network.py:
import socket
class Network:
def __init__(self):
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server = "XXXXXX" # will always be the same
self.port = 5555
self.address = (self.server, self.port)
self.id = self.connect()
print(self.id)
def connect(self):
try: # trying to connect
self.client.connect(self.address)
return self.client.recv(2048).decode()
except:
pass
n = Network()
Thank you for the help

Running an echo server as a daemon process for testing in python

I want to automate testing of an instrument and wrote a little server program to imitate the instrument which will send back the command except when it receives a special command "*IDN?". When I ran the echo server directly in its own script, and then run a client script separately, everything works great, and I am getting back the expected results. Now I wanted to run the server directly from the testing script. So I thought I would start it using multiprocessing. But the problem seems to be when the server socket gets to the s.accept() line it just waits there and never returns. So how do I accomplish automated testing if I cannot run this server in the same code as the test function?
import socket
import multiprocessing as mp
import time,sys
HOST = '127.0.0.1' # Standard loopback interface address (localhost),
PORT = 65432 # Port to listen on (non-privileged ports are > 1023),
FTP_PORT = 63217 # Port for ftp testing, change to 21 for device
def handle_connection(conn,addr):
with conn:
conn.send('Connected by', addr)
print("Got connection")
data = conn.recv(1024)
if not data:
return 'Nodata'
elif (data == b'*IDN?\n'):
print('SONY/TEK,AWG520,0,SCPI:95.0 OS:3.0 USR:4.0\n')
conn.sendall(b'SONY/TEK,AWG520,0,SCPI:95.0 OS:3.0 USR:4.0\n')
return 'IDN'
else:
conn.sendall(data)
return 'Data'
def echo_server(c_conn,host=HOST,port=PORT):
# this server simulates the AWG command protocol, simply echoing the command back except for IDN?
p = mp.current_process()
print('Starting echo server:', p.name, p.pid)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((host, port))
s.listen()
try:
while True:
print("Waiting for connection...")
c_conn.send('waiting for connection...')
conn, addr = s.accept()
handle_connection(conn,addr)
c_conn.send('serving client...')
finally:
conn.close()
c_conn.send('done')
time.sleep(2)
print('Exiting echo server:', p.name, p.pid)
sys.stdout.flush()
def test_echo_server():
print("entering client part")
with socket.socket(socket.AF_INET,socket.SOCK_STREAM) as mysock:
mysock.connect((HOST,PORT))
mysock.sendall('test\n'.encode())
data = mysock.recv(1024)
print('received:',repr(data))
if __name__ == '__main__':
parent_conn, child_conn = mp.Pipe()
echo_demon = mp.Process(name='echo', target=echo_server(child_conn, ))
echo_demon.daemon = True
echo_demon.start()
time.sleep(1)
echo_demon.join(1)
test_echo_server()
if parent_conn.poll(1):
print(parent_conn.recv())
else:
print('Waiting for echo server')
I managed to solve my own question using some code snippets I found in the book "Getting started with Python" by Romano, Baka, and Phillips. here is the code for the server:
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()
try:
while True:
print("Waiting for connection...")
client, addr = s.accept()
with client:
data = client.recv(1024)
if not data:
break
elif (data == b'*IDN?\n'):
client.sendall(b'SONY/TEK,AWG520,0,SCPI:95.0 OS:3.0 USR:4.0\n')
else:
client.sendall(data)
finally:
time.sleep(1)
print('Exiting echo server:')
and here is the code for the testing file which runs this server in a separate process, and a couple of simple tests:
#pytest.fixture(scope="session")
def awgserver():
print("loading server")
p = subprocess.Popen(["python3", "server.py"])
time.sleep(1)
yield p
p.terminate()
#pytest.fixture
def clientsocket(request):
print("entering client part")
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as mysock:
mysock.connect((HOST, PORT))
yield mysock
mysock.close()
#pytest.mark.run_this
def test_echo(awgserver, clientsocket):
clientsocket.send(b"*IDN?\n")
#assert clientsocket.recv(1024) == b"SONY/TEK,AWG520,0,SCPI:95.0 OS:3.0 USR:4.0\n"
assert clientsocket.recv(10) == b"TEK" # deliberately make test fail
#pytest.mark.run_this
def test_echo2(awgserver, clientsocket):
clientsocket.send(b"def")
assert clientsocket.recv(3) == b"def"
Set HOST to loopback IP, and PORT to > 1024

Categories