user14303139
user14303139

Reputation: 1

Why does socket become disconnected?

I am trying to create a chat server between 2 machines but there's a problem with the connection. Although it initially connects, when it comes to sending any actual data the socket becomes disconnected.

Server code

import socket
import sys
import time
messages = []

x= socket.socket()
h_name = socket.gethostname()
print('Server will start on host address:', h_name)
port = 8000

bind = False
while bind == False:
   try:
      x.bind((h_name, port))
      bind = True
      print('This server is running on port', port)
   except(OSError): #if the port connection doesn't work
      if port == 65535:
         print('Please restart the machine and relaunch this program')
      else:
         port = port + 1 #increment the port by 1 and try again
         print('Trying Port ' + str(port) + '...')

print( "Server done binding to host and port successfully")
print("Server is waiting for incoming connections")
x.listen(1)
connection,address= x.accept()
print(address, "has connected to the server and is now online...")

while 1:
   display_mess= input(str(">>"))
   if display_mess == 'QUIT': #if the user wants to quit
      confirmation = input('Are you sure you would like to quit (Y/N)? ')
      confirmation = confirmation.upper()
      if confirmation == 'Y':
         print('Press enter to quit...')
         input()
         exit()
   else:
   display_mess=display_mess.encode()
   connection.send(display_mess)
   print("Message has been sent...")
   in_message=connection.recv(1024)
   in_message=in_message.decode()
   print("Client:", in_message)

The above code should set up a server and wait for a connection from the client and then they should be able to communicate, albeit one single message at a time. The server should send the message first and then the client.

Client code

import socket
import sys
import time
global port
port = 8000


def getHostName():
   global h_name
   h_name= input(str("Enter the hostname of the server: "))

def portConnect(h_name,port):
   x = socket.socket()
   connected = False
   while connected == False:
      x = socket.socket()
      try:
         x.connect((h_name,port))
         print("Connected to chat server")
         connected = True
      except(ConnectionRefusedError):
         print('Port', port, 'is incorrect')
         print('Trying port ' + str(port+1) + '...')
         port = int(port+1)
         portConnect(h_name,port)

def while1():
   x = socket.socket()
   while 1:
      x = socket.socket()
      try:
         incoming_message=x.recv(1024)
         incoming_message=incoming_message.decode()
         print(" Server :", incoming_message)
         message= input(str(">>"))
         if message == 'QUIT':
            confirmation = input('Are you sure you would like to quit (Y/N)? ')
            confirmation = confirmation.upper()
            if confirmation == 'Y':
               print('Press enter to quit...')
               input()
               exit()
            else:
               message =message.encode()
               x.send(message)
               print(" message has been sent...")
         else:
            message =message.encode()
            x.send(message)
            print(" message has been sent...")

      except(OSError):
         print('Please check the server machine is running')
         cont = input('Would you like to quit the program or continue (Q/C): ')
         if cont.isnum() != True and len(cont) > 0:
            cont = cont.upper()
            if cont == 'C':
               getHostName()
            else:
               print('Press enter to exit')
               input()
               exit()

getHostName()
portConnect(h_name, port)
while1()

The above code should create a client machine and search for the server on the predetermined port and LAN and wait for a connection from the server and then they should be able to communicate, albeit one single message at a time. The server should send the message first and then the client.

Console output (on client's machine')

Enter the hostname of the server: *name*
Connected to chat server
Traceback (most recent call last):
  File "******.py", line 71, in <module>
    while1()
  File "******.py", line 38, in while1
    incoming_message=x.recv(1024)
OSError: [Errno 57] Socket is not connected

The console output says they do initially connect as it displays the Connected to chat server message but then they disconnect as the server cannot send any message.

If the server tries to send a message after the socket has been disconnected, the console output is:

Traceback (most recent call last):
  File "******.py", line 43, in <module>
      in_message=connection.recv(1024)
  ConnectionResetError: [Errno 54] Connection reset by peer

I imagine, however, this issue will solve itself after the socket problem has been sorted.

Upvotes: 0

Views: 599

Answers (1)

Carcigenicate
Carcigenicate

Reputation: 45826

The big hint as to what's wrong is looking at how many times you call socket.socket in the client code. I see four different places where you create a new socket: twice in while1, and twice in portConnect. That's surely not what you want. Your code is failing because you connect the socket created in portConnect, then that socket object goes out of scope when the function exits. The x in portConnect is not the same x in while1.

I'd pass x in to portConnect instead of using the newly created socket:

def portConnect(h_name, port, x):
    # Don't create a new socket here
    connected = False
    while connected == False:
        # Also don't create a new socket here
    . . .

Then move the call to portConnect to somewhere where x is in scope, and call it as:

portConnect(h_name, port, x)

You also probably want to get rid of the x = socket.socket() inside of the while 1: loop.

You could also create x in portConnect, and then return it from the function. You may find that that makes more sense.


A few side things:

  • while1 is a very poor name for a function. The name should describe what the function does, not details about its implementation.

  • while 1 is more clear as while True.

  • Conditions like while connected == False: are more readable and idiomatic as while not connected:. Comparing against True and False directly is never necessary.

Upvotes: 2

Related Questions