2015-10-13 143 views
2

我试图编写一个Python版本的例子here,但由于某种原因,每次调用socket.recvfrom()时,我都会在客户端和服务器端进行编程, address返回值是None。我唯一能想到的就是它可能与插座是STREAM插座的事实有关,但是当我尝试将其类型更改为socket.SOCK_DGRAM时,我在致电socket.listen()时遇到错误。我该如何解决这个问题?Python:socket.recvfrom()返回地址

def server(port): 
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    sock.bind(('127.0.0.1', port)) 
    sock.listen(5) 
    clientsocket, address = sock.accept() 

    kkp = KnockKnockProtocol(); #Class which implements knock knock 
    outputLine = kkp.processInput(); 
    clientsocket.sendto(outputLine, address) 

    inputLine, address = clientsocket.recvfrom(MAX_BYTES) 

    while inputLine: 
     print inputLine, address 
     outputLine = kkp.processInput(inputLine); 
     clientsocket.sendto(outputLine, address) 
     if outputLine == "Bye.": 
      break 
     inputLine, address = clientsocket.recvfrom(MAX_BYTES) 


def client(port): 
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    sock.connect(("127.0.0.1", port)) 
    fromServer, address = sock.recvfrom(MAX_BYTES) 

    while fromServer: 
     print "Server: " + fromServer 
     if fromServer == "Bye.": 
      break 

     fromUser = raw_input() 
     if fromUser: 
      print "Client: " + fromUser 
      sock.sendto(fromUser, ("127.0.0.1", port)) 
     fromServer, address = sock.recvfrom(MAX_BYTES) 


if __name__ == '__main__': 
    choices = {'client': client, 'server': server} 
    parser = argparse.ArgumentParser(description='Send and receive UDP locally') 
    parser.add_argument('role', choices=choices, help='which role to play') 
    parser.add_argument('-p', metavar='PORT', type=int, default=1060, help='UDP port (default 1060)') 
    args = parser.parse_args() 
    function = choices[args.role] 
    function(args.p) 

回答

2

可以使用数据报套接字或流套接字。你正试图分化差异。你想用哪个?如果您想要基于连接的字节流协议,请使用流套接字。如果你想要一个无连接的数据报协议,使用数据报套接字。

如果您想使用流套接字,请不要使用recvfrom。它基于连接,您可以接收的唯一东西是来自该特定连接的字节。

如果要使用数据报套接字,请不要使用listenaccept。既然它没有连接,你既不能听也不能接受连接。

+0

好吧,那么如果我想使用流套接字,那么如何将数据发送回另一端的套接字?同样,如果我想使用数据报套接字,我只是直接发送到一个地址? –

+2

@SimonZhu对于流套接字,您可以使用'write'将其发送到流的另一端。对于数据报套接字,你可以使用'sendto'发送到一个特定的地址。 –