Python3.6, OSError: [Errno 57] Socket is not connected

匿名 (未验证) 提交于 2019-12-03 01:45:01

问题:

I was trying to write a protocol like UDP in python, which include some details like three_handshake, but I can't run the server.py cause it told me like this:

Traceback (most recent call last): File "/Users/suiyoucheng/PycharmProjects/9331 ASS/receiver.py", line  38, in <module> BYTE_fh, senderAddress = receiverSocket.recvfrom(1024) OSError: [Errno 57] Socket is not connected 

and my server.py code shown as below:

try:     receiverSocket = socket(AF_INET, SOCK_STREAM) except:     print("Failed to create receiver socket.")     sys.exit()   receivePort = 2000 try:     receiverSocket.bind(('', receivePort)) except:     print("Bind failed.")     sys.exit()  #                           First Hand Shake                              #  receiver_ISN = 0 receiver_ITIME = time.time()   BYTE_fh, senderAddress = receiverSocket.recvfrom(1024) #**where I got wrong**# first_hand = pickle.loads(BYTE_fh) 

Could you guys tell me how to fix that? Thank you so much.

回答1:

You will need a client socket as well to test the server. Below is a more complete ClientSocket class that can be used. You can use the function cnsdrcv() for a one time send-receive interaction. The same class can also be used on the server-side for interacting with the client connections -

connection, client_address = serverSocket.accept() clntCon = ClientSocket() clntCon.useSocket(connection).connect() dataBytes = clntCon.rcvAllSent() # Process all the "dataBytes" and then respond back clntCon.send(responseBytes) clntCon.close()  #----------------------------------------------------------------------------------------------------------  def cnsdrcv(host, port, data, timeout=1):   # data - bytes()   # returns data chunks as list of bytes()    # Create a TCP/IP socket   sock = ClientSocket()   sock.useHost(host, port, timeout)    try:     sock.connect()      # Send data     sock.send(data)      return sock.rcvUntilTimeout()   finally:     sock.close() 

The complete class below -

class ClientSocket:    def __init__(self, name=None):     logging.debug("ClientSocket [{}] : __init__()".format(name))     self.Name = name     self.sock = None     self.server_address = None    @property   def Name(self):     if self.__Name is None and self.server_address is not None:       self.Name = str(self.server_address[1])      return self.__Name    @Name.setter   def Name(self, name):     self.__Name = name    @Name.deleter   def Name(self):     del self.__Name     def useSocket(self, sock, timeout=1):     # Socket is assumed to be already connected     logging.debug("ClientSocket [{}] : useSocket()".format(self.Name))      if sock is None:       raise ValueError("ClientSocket.useSocket() : sock arg cannot be None")      if self.sock is None:       self.server_address = sock.getpeername()       self.sock = sock       self.timeout = timeout       self.sock.settimeout(self.timeout)       return self     else:       raise AttributeError("ClientSocket.useSocket() : is already in use")     def useHost(self, host, port, timeout=1):     logging.debug("ClientSocket [{}] : useHost()".format(self.Name))      if host == None or len(host) == 0:       host = socket.gethostname()     self.server_address = (host, port)     self.timeout = timeout     def connect(self):     logging.debug("ClientSocket [{}] : connect()".format(self.Name))      if self.sock is None:     # Create a TCP/IP socket       self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)       logging.info('connecting to {} port {}'.format(*self.server_address))        # Connect the socket to the port where the server is listening       self.sock.connect(self.server_address)       self.sock.settimeout(self.timeout)     else:       self.isValid()     def isValid(self):     if not self.sock:       return False      try:       if self.sock.fileno() == -1:     except:       return False      try:       self.sock.getsockname()     except socket.error as e:       if e.args[0] == errno.EBADF:         # Socket is CLOSED         pass       return False      try:       self.sock.getpeername()     except socket.error as e:       if e.args[0] in [errno.EBADF, errno.ENOTCONN]:         # Socket is CLOSED         pass       return False      return True     def send(self, data):     # data must be a bytes or Data object     logging.debug("ClientSocket [{}] : send()".format(self.Name))      logging.debug('sending {!r}'.format(data))      if not self.isValid() :       logging.error("Client Socket in BAD state, cannot send")      if isinstance(data, str):       data = data.encode()      try:       # Send data       self.sock.sendall(data)     except:       raise    def rcvOnce(self, rcvSz, timeout=5):     # receive at least one byte, waiting for timeout secs     # returns bytes containing max rcvSz bytes     logging.debug("ClientSocket [{}] : rcvOnce()".format(self.Name))      if not self.isValid() :       logging.error("Client Socket in BAD state, cannot receive")       return None      strtTime = time.time()     while True:       try:         chunk = self.sock.recv(rcvSz)         break       except socket.timeout:         logging.debug("Socket recv timedout, re-trying")         if time.time() - strtTime >= timeout:           raise         continue       except:         logging.exception("Receive exception")         raise      if chunk is None or len(chunk) == 0:       logging.debug("Received len [0]")     else:       logging.debug("Received len [{}]".format(len(chunk)))      return chunk    def rcvAllSent(self, timeout=5):     # Returns a Data object     logging.debug("ClientSocket [{}] : rcvAllSent()".format(self.Name))      if not self.isValid() :       logging.error("Client Socket in BAD state, cannot receive")       return None      chunks = []     strtTime = time.time()     while True:       try:         chunk = self.sock.recv(1024)       except socket.timeout as e:         logging.debug("Read Timeout occurred [{}]".format(e))         if time.time() - strtTime >= timeout:           raise         continue       except socket.error as e:         logging.error("Some Socket error occurred [{}]".format(e))         break       else:         if len(chunk) == 0:           logging.info("Received empty chunk, could be due to socket close()")           break         else:           chunks.append(chunk)           if len(chunk) < 1024:             break           else:             continue      return b''.join(chunks)    def rcvUntilTimeout(self, rcvSz=2048):     # returns a list of received bytes() objects     logging.debug("ClientSocket [{}] : rcvUntilTimeout()".format(self.Name))      if not self.isValid() :       logging.error("Client Socket in BAD state, cannot receive")       return None      chunks  = []     tchunkb = []      chunk = self.rcvOnce(rcvSz)     if chunk is None or len(chunk) == 0:       # Socket closed by the remote       return None     else:       chunks.append(chunk)      while True:       try:         chunkb = self.sock.recv(rcvSz)       except socket.timeout as e:         logging.debug("Socket recv timedout")         break       except socket.error:         logging.exception("Socket recv error")         raise       except:         logging.exception("Unknown Exception while recv")         raise       else:         if len(chunkb) == 0:           logging.info("Received empty chunk indicating remote end closed the socket")           break         else:           logging.debug("Received len [{}]".format(len(chunkb)))           tchunkb.append(chunkb)           if len(chunkb) < rcvSz:             chunks.append(b''.join(tchunkb))             tchunkb = []           else:             continue      return chunks    def close(self):     logging.debug("ClientSocket [{}] : close()".format(self.Name))      if self.isValid():       self.sock.shutdown(socket.SHUT_RDWR)       self.sock.close() 


回答2:

You need to start listening for connections before you can read the data from the socket. Please add receiverSocket.listen() and receiverSocket.accept() after the bind(). Rather than using raw socket, you can use the socketserver as well.

The overall steps that need to be taken for creating a server (without exception handling):

srvsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_address = (socket.gethostname(), 25000) srvsock.bind(server_address) srvsock.listen(5) connection, client_address = srvsock.accept() data = connection.recv(1024) 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!