0

The idea is to create a server for sending and receiving files for backup, right now the server receives 1 msg from a client in python and another in C++, the problem is, the python client manages to send 1 string and then the server kinda looks, and I have to end the connection, that's for the python client, when I'm trying to send data from the c++ client i got nothing

I'm using Websockets, but my problem seems to be on the try: statement, honestly cant figure it out wheres my problem

sidenote: I'm using quit() to stop my program, but every time I used it I got way too many errors so I had to comment it

Here's my Server.py code

import asyncio
import websockets
import socket
import sqlite3 
import sys


def get_ip():    # returns primary private IP only
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        # doesn't even have to be reachable
        s.connect(('10.255.255.255', 1))
        IP = s.getsockname()[0]
    except Exception:
        IP = '127.0.0.1'
    finally:
        s.close()
    return IP


async def handle_connectio(websocket, path):  # recive and handle connection from client, would handle json or file data
    while True:
        try:
            async for name in websocket:
                #name = await websocket.recv()
                print(f"<<< {name}")
            #break
        except websockets.exceptions.ConnectionClosed:
            print (f"Coneecion terminada")
            #quit()
            break
        else:
            print (f"algo paso")
            #quit()
            break
        

print ("Iniciando el Server webSocket")
print ("Current Ip: " + get_ip())
servidor = websockets.serve(handle_connectio, get_ip(), 8000)

#loop = asyncio.get_event_loop()
#loop.run_until_complete(servidor)
asyncio.get_event_loop().run_until_complete(servidor)
asyncio.get_event_loop().run_forever()
        
#async def main():  # main function
#    print ("Iniciando Server websocket")
#    print("Current Ip: " + get_ip())
#    async with websockets.serve(handle_connectio, get_ip(), 8000):
#        await asyncio.Future()


#if __name__ == '__main__':
#    asyncio.run(main())

edit: I did try to simplify my code and it manages to receive the msg and show when the connection is closed - still the main problem persists.

async def handle_connectio(websocket, path):  # recive and handle connection from client, would handle json or file data
    try:
        while True:
        #async for data in websocket:
            data = await websocket.recv()
            print(f"<<< {data}")
            await asyncio.sleep(1)
    except websockets.exceptions.ConnectionClosed:
        print (f"Coneecion terminada")

edit2: heres my client code, if this donst work i would switch to sockets

import asyncio
import websockets

async def client():
    direc = "ws://192.168.1.69:8000"
    async with websockets.connect(direc) as web:
        while True:
            nombre = input("Introduce el mensaje >>> ")
            await web.send(nombre)
            
            
asyncio.get_event_loop().run_until_complete(client())
mike65535
  • 483
  • 2
  • 10
  • 21
lightshadown
  • 165
  • 1
  • 1
  • 10

2 Answers2

0

From looking at and running the example code at https://websockets.readthedocs.io/en/stable/, it's apparent that your connection handler shouldn't loop forever (while True:) but exit after handling all the messages supplied by the websocket. It will be called again when another message arrives.

Edit:

The original server code works fine. The problem is that the client is using the input() function, which blocks asyncio from running, which prevents websocket protocol from running correctly and blocks messages from sending. A small delay after send (await asyncio.sleep(1)) works, although ideally the input() and the asyncio comm logic would be separated, to avoid an arbitrary delay.

dirck
  • 838
  • 5
  • 10
  • i did try that exac same code and i got the same behaivior, for some odd reason my code tends to wait for something or its missing something not sure, plz check the edit – lightshadown Oct 26 '21 at 16:07
  • You've switched the code from `for item in websocket` iterator as in the example, to using `websocket.recv()`. I haven't tested `recv`, but examples for `recv` use the while loop. Perhaps you could post your client code... The example code from the link works. – dirck Oct 26 '21 at 17:52
  • I will try to run your server against the example client and see what happens... – dirck Oct 26 '21 at 18:02
  • I changed the server to echo (`await websocket.send(name)`, etc) and both the old and new `handle_connectio` functions work fine with the example client; removing echo from server and client and it also works fine. I'm not sure what you're seeing with the server locking up, or why your c++ client doesn't work. Why do you think the server is locked up? – dirck Oct 26 '21 at 18:07
  • ok sorry, i would post my client code, check edit – lightshadown Oct 26 '21 at 18:15
  • ok for some odd reason websockets behave in an extrange way, i had to switch to sockets and manage to send an recieve the data i need, either using the python and c++ client, i would post my code as an asnwer thanks anyway for the help – lightshadown Oct 26 '21 at 18:39
  • 1
    I've updated the answer with what I've found using your client code. Be aware that raw sockets are not as transactional as websockets, this can cause surprises when your messages get larger. – dirck Oct 26 '21 at 18:47
0

Ok for some odd reason websockets wont work/behave properly so i had to switch to Sockets and now i can send the data back and forth, i would post my client and server code for anyone on the future.

Server.py

import socket

# socket.SOCK_STREAM -> TCP
# socket.SOCK_DGRAM -> UDP

def get_ip():    # returns primary private IP only
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        # doesn't even have to be reachable
        s.connect(('10.255.255.255', 1))
        IP = s.getsockname()[0]
    except Exception:
        IP = '127.0.0.1'
    finally:
        s.close()
    return IP

def servidor():
    print (f"Iniciando el Servidor Sockets")
    print (f"Current IP Addres: " + get_ip())
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind((get_ip(), 8000))

    server.listen(1)
    conn, address = server.accept() # Accept the Client connection

    while True:
        #1024 is the bandwidth bits 
        try:
            msg = conn.recv(1024).decode() # Recive the msg and trasform it from Binary to String
            print("<<< " + msg)
        except:
            print (f"coneccion terminada")
            break
  
if __name__ == "__main__":
    servidor()

Client.py

import socket

print ('Iniciando cliente')
conn_client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
conn_client.connect( ('192.168.1.68', 8000))

while True:
    try:
        msg = (f">>> ")
        conn_client.sendall(msg.encode())
    except:
        print (f"Connection Close")
        break
#recibido = conn_client.recv(1024)

#print (recibido.decode())
conn_client.close()
lightshadown
  • 165
  • 1
  • 1
  • 10