0

I'm trying a simple send/receiver example on my local machine using TCP. The goal is to open a TCP server and send some data. My setup is Python3.6 on Pycharm IDE. I have enabled parallel run of the sender and receiver scripts.

Here is the Server script:

import socket
import sys

# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Bind the socket to the port
server_address = ('localhost', 5005)
print(sys.stderr, 'starting up on %s port %s' % server_address)
sock.bind(server_address)

# Listen for incoming connections
sock.listen(1)

while True:
    # Wait for a connection
    print(sys.stderr, 'waiting for a connection')
    connection, client_address = sock.accept()
    try:
        print(sys.stderr, 'connection from', client_address)

        # Receive the data in small chunks and retransmit it
        while True:
            data = connection.recv(16)
            print(sys.stderr, 'received "%s"' % data)
            if data:
                print(sys.stderr, 'sending data back to the client')
                connection.sendall(data)
            else:
                print(sys.stderr, 'no more data from', client_address)
                break

    finally:
        # Clean up the connection
        connection.close()

And here is the client script:

import socket
TCP_IP = 'localhost'
TCP_PORT = 5005
BUFFER_SIZE = 1024
MESSAGE = "Hello, World!"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(MESSAGE.encode('utf-8'))

I verified that both scripts are running and I've used the debugger to parse each line on the sender side. I get no errors but I also don't see that the server receives anything.

EDIT: I have used an example code from this page Server:

#!/usr/bin/env python3

import socket

HOST = '127.0.0.1'  # Standard loopback interface address (localhost) PORT = 65432        # Port to listen on (non-privileged ports are > 1023)

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind((HOST, PORT))
    s.listen()
    conn, addr = s.accept()
    with conn:
        print('Connected by', addr)
        while True:
            data = conn.recv(1024)
            if not data:
                break
            conn.sendall(data + b' from server')

Client:

#!/usr/bin/env python3

import socket

HOST = '127.0.0.1'  # The server's hostname or IP address
PORT = 65432        # The port used by the server

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((HOST, PORT))
    s.sendall(b'Hello, world')
    data = s.recv(1024)

print('Received', repr(data))

And I get the expected result:

Received b'Hello, world from server'

Marco Bob
  • 59
  • 6
  • What all gets printed on the server-side? Also, for your prints, do you mean `print('connection from', client_address, file=sys.stderr)` to print to the stdout? Your current code just prints the object itself. – Carcigenicate Jul 07 '21 at 13:51
  • @Carcigenicate thank you. I have used a more recent code example (please view my edit). The example code works now – Marco Bob Jul 07 '21 at 13:57

1 Answers1

0

Hmm, the client scripts ends immediately after sending its data... This is at least dangerous! Race conditions could cause the connection to be destroyed before anything has been correctly received by the peer. The robust way would be to use a graceful shutdown client side:

...
s.send(MESSAGE.encode('utf-8'))
s.shutdown(socket.SHUT_WR)     # tell peer we have nothing more to send
while True:
    data = s.recv(256)
    if len(data) == 0:         # but keep on until peer closes or shutdowns its side
        break

After that, I could test that your server script could correctly receive and send back the message:

<idlelib.run.StdOutputFile object at 0x0000021279F1CBB0> starting up on localhost port 5005
<idlelib.run.StdOutputFile object at 0x0000021279F1CBB0> waiting for a connection
<idlelib.run.StdOutputFile object at 0x0000021279F1CBB0> connection from ('127.0.0.1', 62511)
<idlelib.run.StdOutputFile object at 0x0000021279F1CBB0> received "b'Hello, World!'"
<idlelib.run.StdOutputFile object at 0x0000021279F1CBB0> sending data back to the client
<idlelib.run.StdOutputFile object at 0x0000021279F1CBB0> received "b''"
<idlelib.run.StdOutputFile object at 0x0000021279F1CBB0> no more data from ('127.0.0.1', 62511)
<idlelib.run.StdOutputFile object at 0x0000021279F1CBB0> waiting for a connection
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252