0

I'm trying to translate an functional UDP socket I have to TCP, but I'm having a hard time because I can't find the explanation why I can't get inputs to work on the TCP. The same code, in UDP, would work. In TCP I simply get a 'blank' input.

Client Side

    elif cmd[0] == 'INSERT':
        name = input("\nNAME: ")
        artist = input("ARTIST: ")
        album = input("ALBUM NAME: ")
        year = input("YEAR: ")
        newsong = name + ";" + artist + ";" + album + ";" + year + "\n"
        sock.sendto(bytes(newsong, "UTF-8"), serv)

Server Side

        elif cmd[0].upper() == 'INSERT':
            with open("songs.txt", "a", encoding='UTF-8') as fd:
                receive_message = con.recvfrom(TAM_MSG)
                msg = receive_message[0]
                fd.write(str(msg, "UTF-8"))
                fd.close()

That totally works in UDP, but not in TCP. Is there any way I can input to the TCP server? How? Thank you.

Aleczk
  • 1
  • TCP servers require both a `bind()` and `listen()` . UDP servers only require a `bind()`. See https://wiki.python.org/moin/TcpCommunication and https://wiki.python.org/moin/UdpCommunication. UDP servers just listen for any messages that come to them from whatever sources, while TCP servers actually need to create a two-way stream. – Frank Yellin Dec 17 '20 at 18:07
  • I agree with Frank, can you post more complete code about how you create either end of the socket? – thomas.cloud Dec 17 '20 at 18:09
  • Thank you for the answer. I read about the streaming and found an answer. I thought the problem was the client, but since you said it's two stream I tried on the server. Just adding the line ```con.send(str.encode(f"Inserting new song: "))``` before the ```with open``` on the server side did the trick! Thank you guys! – Aleczk Dec 17 '20 at 18:24
  • It's more work than that. TCP isn't messaged-based like UDP, so you need a protocol to read the TCP byte stream and break it up into valid messages. Think about a TCP stream like a file. You need some protocol to know where lines end (look for newlines) or binary structures start and end (provide a length). – Mark Tolonen Dec 17 '20 at 18:35

1 Answers1

0

Well, I read about TCP and it needs to have a two-way stream, as the guys pointed in the commentaries.

Adding just one line at the start of the server.py made the trick.

con.send(str.encode(f"Inserting a new song: "))

Thanks everybody!

P.S: This is certainly not the best answer, since I'm a newbie. I just got lucky I guess, so that worked for me.

Aleczk
  • 1
  • 1
    It works until it breaks. `send(b'message1'); send(b'message2')` and `data = recv(1024)` could receive `b'message1mess'`. TCP only guarantees the bytes will be received in the same order, but not with the same breaks. A `recv(x)` will return zero (socket closed) or 1 to x bytes from the stream. Buffer the data and provide a length or sentinel value in the data to find messages. – Mark Tolonen Dec 17 '20 at 18:44
  • For example: https://stackoverflow.com/q/46894768/235698 – Mark Tolonen Dec 17 '20 at 18:49