我试图在python中编写类似UDP的协议,其中包含诸如three_handshake之类的一些详细信息,但是我无法运行server.py,因为它这样告诉我:
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
和我的server.py代码如下所示:
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)
你们能告诉我如何解决吗?非常感谢。
答案 0 :(得分:0)
您需要开始侦听连接,然后才能从套接字读取数据。 请在bind()之后添加receiverSocket.listen()和receiverSocket.accept()。 除了使用原始套接字,还可以使用socketserver。
创建服务器所需的总体步骤(无异常处理):
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)
答案 1 :(得分:0)
您还将需要一个客户端套接字来测试服务器。下面是可以使用的更完整的ClientSocket类。您可以一次使用cnsdrcv()函数进行收发交互。在服务器端也可以使用相同的类与客户端连接进行交互-
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()
下面的完整课程-
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()