VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > Java教程 >
  • 01tcp_deadlock.py

import argparse,socket

def recvall(sock,length):
    """传入一个套接字,和一个长度"""
    # 定义一个二进制的变量
    data = b''
    # 循环
    while len(data) < length:
        print(len(data),length)
        # more用来接收规定长度减去data的长度
        # 注意这里,recv函数是阻塞的,如果他没有接收到数据,那么就一直卡在那里。
        # 有两种情况,如果每次发送的数据都比我们设定的长度要少,那么第二次循环,就会卡主
        # 还有一种就是我们发送的字节数正好是我们规定长度的整数倍,那么最后一次循环就为空了。
        # 针对这个,我们可以在发送端和接收端都来一个结束标识。
        more = sock.recv(length - len(data))
        if more == b'efo':break
        if not more:
            raise EOFError('was expecting %d bytes but only received '
                           'd% bytes before the socket closed ' %(length ,len(data)))
        data += more
    return data

def server(interface,port):
    # 定义一个套接字,用于TCP连接
    sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    # 设置套接字连接
    sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    # sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    # 套接字绑定端口和IP地址
    sock.bind((interface,port))
    # 设置套接字的监听客户端的监听数量。
    sock.listen(1)
    # 打印出服务端连接绑定的IP地址和端口
    print("listening at",sock.getsockname())
    # 死循环遍历,用来重复的进行和监听服务端,然后进行通信。
    while True:
        # 服务端套接字用来接收客服端的连接请求。
        sc,socketname = sock.accept()
        print("We have accepted a connection from",socketname)
        print("  Socket name:",sc.getsockname())
        print("  Socket peer:",sc.getpeername())
        # 规定每次接收客户端传过来的消息长度
        message = recvall(sc,16)
        print('222222')
        # 打印出来接受到的数据。
        print(' Incoming sixteen-octet message:',repr(message))
        # 服务端发送二进制消息。
        sc.sendall(b'Farewell,client')
        sc.sendall(b'efo')
        sc.close()
        print("  Reply sent ,scoket closed")

# 定义客户端函数,入参为IP地址和端口
def client(host,port):
    # 定义一个TCP 连接的套接字。
    sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    # 建立和服务端的TCP连接。
    # 注意这里传入的是一个元祖
    sock.connect((host,port))
    # 打印客户端连接的IP和端口
    print('Client has been assigned socket name',sock.getsockname())
    # 客户端发送二进制消息
    sock.sendall(b'Hi there,server')
    # 发送一个结束标识
    sock.sendall(b'efo')
    # 客户端接收服务端发送过来的消息
    reply = recvall(sock,16)
    # 打印出来服务端发送的消息
    print('222222')
    print('The server said' ,repr(reply))
    # 关闭套接字
    sock.close()

if __name__ == "__main__":
    # 定义一个字典
    choices = {'client':client,'server':server}
    parser = argparse.ArgumentParser(description = 'Send and receive over TCP')
    parser.add_argument('role',choices = choices,help = 'which role to play')
    parser.add_argument('host',help = 'interface the server listens at;'
                                      ' host the client sends to')
    parser.add_argument('-p',metavar = "PORT",type = int,default = 1060,help = "TCP port (default 1060")
    args = parser.parse_args()
    function = choices[args.role]
    function(args.host,args.p)

出处:https://www.cnblogs.com/cong12586/p/13924635.html

 

相关教程