0

I have a listener on a tcp localhost:

HOST = '127.0.0.1'  # The server's hostname or IP address
PORT = 8192         # The port used by the server
def client_socket():
    while 1:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.bind((TCP_IP,TCP_PORT))
        s.listen(1)
        while 1:
            print 'Listening for client...'
            conn, addr = s.accept()
            print 'Connection address:', addr
            data = conn.recv(BUFFER_SIZE)
            if data == ";" :
                conn.close()
                print "Received all the data"
                i=0
                for x in param:
                    print x
                #break
            elif data:
                print "received data: ", data
                param.insert(i,data)
                i+=1
                #print "End of transmission"
        s.close()

I am trying to send a JSON object to the same port on the local host:

HOST = '127.0.0.1'  # The server's hostname or IP address
PORT = 8192         # The port used by the server
def json_message(direction):

    local_ip = socket.gethostbyname(socket.gethostname())
    data = {
        'sender' : local_ip,
        'instruction' : direction
    }

    json_data = json.dumps(data, sort_keys=False, indent=2)
    print("data %s" % json_data)

    send_message(json_data)

    return json_data



def send_message(data):
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.connect((HOST, PORT))
        s.sendall(data)
        data = s.recv(1024)

    print('Received', repr(data))

However, I get a socket error:

socket.error: [Errno 98] Address already in use

What am I doing wrong? Will this work or do I need to serialize the JSON object?

4
  • 1
    Your error has nothing to do with JSON... Looks like you already have something running on that port Commented Nov 17, 2018 at 5:17
  • And youre just sending "a string", already serialized, which only happens to be parsable by a JSON parser... Commented Nov 17, 2018 at 5:19
  • Assuming you are running this on a Linux host execute sudo lsof -i :8192 to see if anything is using port 8192. Commented Nov 17, 2018 at 5:32
  • The client_socket is listening on the port. Commented Nov 17, 2018 at 5:50

1 Answer 1

2

There are a few problems with your code, but the one that will likely address your issue is setting the SO_REUSEADDR socket option with:

s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

after you create the socket (with socket.socket(...) but before you attempt to bind to an address (with s.bind().

In terms of other things, the two "halves" of the code are pretty inconsistent -- like you copied and pasted code from two different places and tried to use them? (One uses a context manager and Python 3 print syntax while the other uses Python 2 print syntax...)

But I've written enough socket programs that I can decipher pretty much anything, so here's a working version of your code (with some pretty suboptimal parameters e.g. a buffer size of 1, but how else would you expect to catch a single ;?)

Server:

import socket

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

def server_socket():
    data = []
    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()
        while 1: # Accept connections from multiple clients
            print('Listening for client...')
            conn, addr = s.accept()
            print('Connection address:', addr)
            while 1: # Accept multiple messages from each client
                buffer = conn.recv(BUFFER_SIZE)
                buffer = buffer.decode()
                if buffer == ";":
                    conn.close()
                    print("Received all the data")
                    for x in data:
                        print(x)
                    break
                elif buffer:
                    print("received data: ", buffer)
                    data.append(buffer)
                else:
                    break

server_socket()

Client:

import socket
import json

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

def json_message(direction):
    local_ip = socket.gethostbyname(socket.gethostname())
    data = {
        'sender': local_ip,
        'instruction': direction
    }

    json_data = json.dumps(data, sort_keys=False, indent=2)
    print("data %s" % json_data)

    send_message(json_data + ";")

    return json_data



def send_message(data):
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.connect((HOST, PORT))
        s.sendall(data.encode())
        data = s.recv(1024)

    print('Received', repr(data))

json_message("SOME_DIRECTION")
Sign up to request clarification or add additional context in comments.

4 Comments

Yes your observation is correct. Just trying a few things. I am trying to get the code running in python 2 first. The server is showing an error when I try to run it. "Traceback (most recent call last): File "src/directioncontroller/client.py", line 32, in <module> server_socket() File "src/directioncontroller/client.py", line 9, in server_socket with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: AttributeError: exit "
@SSF Does client show the same issue? an AttributeError blaming __exit__? If so, I guess 2.7 doesn't support sockets as context managers and you'd want to replace with socket.socket(...) as s with s = socket.socket(...).
Yes, it does. Any way to do this in python 2 only?
@SSF Sure, try replacing the with socket.socket() with the s = socket.socket(...) approach as I put in my last comment.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.