Connect two applications using sockets

1

Well my problem is this:

We are starting to see the topic of sockets and I have these examples:

CLIENT:

import socket
host = "localhost"
port = 9999
socket1 = socket.socket()
socket1.connect((host, port))
try:
    while(True):
        cadena = input("Mensaje para enviar al servidor: ")
        socket1.send(cadena.encode(encoding='utf-8'))
        print("se ha enviado la cadena: ", cadena)
        CadenaRecServidor = socket1.recv(1024).decode('utf-8')
        print("El servidor responde: ", CadenaRecServidor)
except Exception as e:
    print("error", e)
socket1.close()

SERVER:

import socketserver


class     MiTcpHandler(socketserver.BaseRequestHandler):
    def handle(self):
        try:
            self.cadena =     self.request.recv(1024).decode('utf-8')
            print("Cliente:", self.cadena)
            self.CadenaSendServer =     input("Sevidor: ")
            self.request.send(self.CadenaSendServer.encode(
                encoding='utf-8',     errors='strict'))
        except Exception as e:
            print("error", e)


host = "localhost"
port = 9999
server1 = socketserver.TCPServer((host, port), MiTcpHandler)
print("Servidor Corriendo")
server1.serve_forever()

My problem is that when executing them, they connect without problems. First I send a message from client to server. Then I reply from the server to the client with another message. The problem is that when trying to send again a third message from client, the program (only client, server if it remains active) closes unexpectedly and shows the following message:

  

error [VinError 10053] A connection established by the software on your host computer has been canceled *

Someone please can help me with this error or have had experience in these cases. Or at least explain why it happens, if I can understand what happens then I solve it myself.

Thanks in advance, I will be here as long as necessary.

    
asked by metamax 27.10.2018 в 02:52
source

1 answer

1

Error 10053 occurs when you try to write from one side of the communication on a socket that has been closed from the other side.

Therefore this indicates that the server has closed the socket after sending the first message to the client. Why did he do that?

This is related to the operation of the socketserver module. In this module, when you invoke serve_forever() the following happens:

  • A passive socket is created (it is a type of listening socket that serves to receive connections) and it is assigned the port that you have indicated (the 9999 in this case).
  • You enter an infinite loop in which:
    • It is expected to receive a connection in that passive socket.
    • When it detects that a connection arrives, create an instance of an object of the class that you passed as a parameter ( MiTcpHandler , in this case). At that moment another socket (data) is created that is assigned to the request field of that object.
    • Call the .handle() of that object, and wait for .handle() to return.
    • Then invoke the method .finish() of that object. In your case you have not programmed that method, so you will use the one you inherit from BaseRequestHandler , which is limited to closing the data socket.
    • The data socket that was used with that client no longer exists (but the passive still does). It returns to the beginning of the loop to wait for another client (which will create another data socket and another instance of MiTcpHandler to handle it, etc.)

So here we have the answer. The framework socketserver expects all network traffic to be handled in the .handle() method. As soon as that method returns it is understood that the communication has ended and therefore the socket is closed.

The solution therefore is to make, within .handle() , a loop that repeats reading and writing the socket several times. If you want to make the server remain in that loop until the client has disconnected, you must use the reception of an empty string as a loop exit condition. That is, if when you do self.request.recv(1024).decode('utf-8') you get "" this means that the other end (the client) has closed the socket. In that case the server can end .handle() so that its socket is closed too.

    
answered by 27.10.2018 / 12:26
source