美文网首页
Python 网络编程 - 04 tcp客户端/tcp服务器

Python 网络编程 - 04 tcp客户端/tcp服务器

作者: flowerflower | 来源:发表于2019-03-09 20:51 被阅读0次
    😝😝

    目录
    一、tcp客户端构建流程
    二、tcp服务器端构建流程
    三、案例——文件下载器
    四、tcp注意点

    一、tcp客户端构建流程

    • 1、创建tcp套接字
    • 2、链接服务器
    • 3、发送/接收数据
    • 4、关闭套接字
    import socket
    
    def main():
    
        # 1. 创建tcp套接字  SOCK_DGRAM:udp  tcp:SOCK_STREAM
        tcp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    
        # 2. 链接服务器
        tcp_socket.connect(("192.168.140.154",7799))
        # 3. 发送/接收数据
        send_data = input("请输入要发送的数据:")
        tcp_socket.send(send_data.encode("utf-8"))
        # 4. 关闭套接字
        tcp_socket.close()
    
    if __name__ == '__main__':
        main()
    
    

    由于已经安装了sokit,现在只需要在终端直接输入sokit则便会启动,之后输入相应的ip以及Port即可

    图片.png

    二、tcp服务器端构建流程

    • 1、创建套接字
    • 2、绑定ip还 Port
    • 3、lisen使用套接字变成被动链接 (让默认的套接字由主动变被动)
    • 4、accept等待客服端连接
    • 5、recv/send接收放发送数据
    • 6、关闭套接字
    import socket
    
    def main():
        # 1. socket创建一个套接字
        utp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    
        # 2. bind绑定ip和port
        utp_socket.bind(("",8855))
    
        # 3.listen使套接字变为可以被动链接
        utp_socket.listen(128)
    
        print("--------1----------")
        # 4. accept等待客户端的链接
        # 返回值是一个元祖
        # 拆包  例如:(a,b) = (1,2)     
        # 如果有新的客户端来链接服务器,那么就产生一个新的套接字专门为这个客户端服务
        # client_socket用来为这个客户端服务
        # tcp_server_socket就可以省下来专门等待其他新客户端的链接
        client_socket,clientAddr = utp_socket.accept()
    
        print("--------2----------")
        print(clientAddr)
    
        # 5.recv / send接收发送数据
        #  接收客服端发送过来的请求
        recv_data = client_socket.recv(1024)  # 接收1024个字节
        print('接收到的数据为: %s' % recv_data)
    
        # 回送一部分数据给客服端
        client_socket.send("-------ok-------".encode("utf-8"))
    
        # 6. 关闭套接字
        client_socket.close()
        utp_socket.close()
    if __name__ == '__main__':
        main()
    
    
    
    图片.png

    tcp服务器循环为多个客户端服务

    import socket
    
    def main():
        # 1. socket创建一个套接字
        utp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        # 2. bind绑定ip和port
        utp_socket.bind(("",8822))
        # 3.listen使套接字变为可以被动链接
        utp_socket.listen(128)
        print("--------1----------")
        # 第一个while循环的目的:为多个客户端服务
        while True:
            print("等待一个新的客户端的到来")
            # 4. accept等待客户端的链接
            # 返回值是一个元祖
            # 拆包  例如:(a,b) = (1,2)
            # 如果有新的客户端来链接服务器,那么就产生一个新的套接字专门为这个客户端服务
            # client_socket用来为这个客户端服务
            # tcp_server_socket就可以省下来专门等待其他新客户端的链接
            client_socket,clientAddr = utp_socket.accept()
            print("一个新的客户端已经到来%s" % str(clientAddr))
            print(clientAddr)
    
            # 第二个while循环的目的:为同一个客户端 服务多次
            while True:
                # recv / send接收发送数据
                # 5. 接收客服端发送过来的请求
                recv_data = client_socket.recv(1024)  # 接收1024个字节
                print('接收到的数据为: %s' % recv_data)
    
                # 如果recv解堵塞,那么有2种方式:
                # 1、客户端发送过来数据
                # 2、客户端调用 close 导致了 这里 recv 堵塞
                if recv_data:
    
                    # 回送一部分数据给客服端
                    client_socket.send("-------ok-------".encode("utf-8"))
                else:
                    print("客户端关闭了自己的套接字或则断开了链接")
                    break
            # 6. 关闭套接字,关闭accept 返回的套接字 意味着 不会在为这个客户端服务
            client_socket.close()
    
        # 如果将监听套接字 关闭了,那么会导致 不能再次等待新客户端的到来,也就是 套接字.accept()会失败
        utp_socket.close()
    
    if __name__ == '__main__':
        main()
    
    
    图片.png

    三、案例——文件下载器

    服务器代码如下:

    import socket
    
    def main():
        # 1.创建socket
        tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        # 2.绑定本地信息
        tcp_server_socket.bind(("192.168.140.148",7800))
        # 3.将主动套接字变为被动套接字
        tcp_server_socket.listen(128)
    
        while True:
    
            print("等待客户端的连接")
            # 4.等待客户端的连接
            new_tcp_socket,client_addr = tcp_server_socket.accept()
            # 5.接收对方发送过来的数据
            recv_data = new_tcp_socket.recv(1024)
            file_name = recv_data.decode("utf-8")
            print("对方请求下载的文件名为:%s" % file_name)
            # 6.处理客户端的内容
            file_content = get_file_content(file_name)
    
            # 发送文件的数据给客户端
            # 因为获取打开文件时是以rb方式打开,所以file_content中的数据已经是二进制的格式,因此不需要encode编码
            if file_content:
                new_tcp_socket.send(file_content)
            # 6.关闭为这个客户端服务的套接字
            new_tcp_socket.close()
        # 7.关闭监听服务器套接字
        tcp_server_socket.close()
    
    def get_file_content(file_name):
        """获取文件的内容"""
        try:
            with open(file_name, "rb") as f:
                content = f.read()
            return content
        except:
            print("没有下载的文件:%s" % file_name)
    
    
    if __name__ == '__main__':
    
        main()
    
    图片.png

    客户端代码如下:

    import socket
    
    
    # 客户端代码
    def main():
    
        # 1.创建socket
        tcp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        # 2.链接服务器
        tcp_socket.connect(("192.168.140.148",8890))
        # 3.获取下载的文件名字
        download_file_name = input("请输入要下载的文件名字:")
        # 4.将文件文字发送到服务器
        tcp_socket.send(download_file_name.encode("utf-8"))
    
        # 5.接收文件中的数据
        recv_data = tcp_socket.recv(1024) # 1024 ----->1K  1024 * 1024 ----->1k *1024 = 1M 1024 * 1024 * 1024 ----->1G
    
        # 6.保存接收到的数据到一个文件中
        if recv_data:
            with open("[新]" + download_file_name, "wb") as file:
                file.write(recv_data)
    
        # 7.关闭套接字
        tcp_socket.close()
    
    if __name__ == '__main__':
    
        main()
    

    四、tcp注意点

    1、tcp服务器一般情况下都需要绑定,否则客户端找不到这个服务器
    2、tcp客户端一般不绑定,因为是主动链接服务器,所以只要确定好服务器的ip、port等信息就好,本地客户端可以随机
    3、tcp服务器中通过listen可以将socket创建出来的主动套接字变为被动的,这是做tcp服务器时必须要做的
    4、当客户端需要链接服务器时,就需要使用connect进行链接,udp是不需要链接的而是直接发送,但是tcp必须先链接,只有链接成功才能通信
    5、当一个tcp客户端连接服务器时,服务器端会有1个新的套接字,这个套接字用来标记这个客户端,单独为这个客户端服务
    6、listen后的套接字是被动套接字,用来接收新的客户端的链接请求的,而accept返回的新套接字是标记这个新客户端的
    7、关闭listen后的套接字意味着被动套接字关闭了,会导致新的客户端不能够链接服务器,但是之前已经链接成功的客户端正常通信。
    8、关闭accept返回的套接字意味着这个客户端已经服务完毕
    9、当客户端的套接字调用close后,服务器端会recv解堵塞,并且返回的长度为0,因此服务器可以通过返回数据的长度来区别客户端是否已经下线

    相关文章

      网友评论

          本文标题:Python 网络编程 - 04 tcp客户端/tcp服务器

          本文链接:https://www.haomeiwen.com/subject/rdgduqtx.html