zoukankan      html  css  js  c++  java
  • python网络编程:udp&tcp&socket

    socket:套接字,在不同主机之间实现通信。
    udp:用户数据报协议。在通信开始前不需要建立连接,只需要发送数据即可。不安全
    tcp:传输控制协议,面向连接。通信双方必须先建立连接才能进行数据传输,双方都必须为连接分配系统内核资源,以管理连接状态和传输数据;完成传输后,双方必须断开连接,释放资源。
    tcp类似于打电话,udp类似于投递信件。因为连接是1对1的,所以tcp不适用于广播的应用程序,基于广播的应用程序使用udp协议。
    单工:只支持数据在一个方向上传输;在同一时间只有一方能接受或发送信息,不能实现双向通信,举例:电视,广播
    半双工:允许数据在两个方向上传输,但是,在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信;在同一时间只可以有一方接受或发送信息,可以实现双向通信。举例:对讲机
    全双工:允许数据同时在两个方向上传输,因此,全双工通信是两个单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力;在同一时间可以同时接受和发送信息,实现双向通信,举例:电话通信
    (图片来自网络,如有侵权请联系删除)

    在python网络编程中,对于udp协议处理流程如下图:

    对于tcp协议的处理流程如下图:

    根据上方流程引出案例:使用udp实现简单的网络通信

    import socket
    
    def send(udp_socket):
        dest_ip=input("请输入目标ip地址:")
        dest_port=int(input("请输入目标端口:"))
        send_date=input("请输入要发送的数据:")
        udp_socket.sendto(send_date.encode('utf-8'),(dest_ip,dest_port))    #向目标ip:port发送数据
    
    def recv(udp_socket):
        recv_data=udp_socket.recvfrom(1024)
        print("%s:%s" % (str(recv_data[1]),recv_data[0].decode('utf-8')))
    
    def main():
        udp_socket=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)      #新建一个ipv4的udp socket
        udp_socket.bind(("",7788))      #为socket绑定一个端口
    
        while True:
            print("---------udp聊天----------")
            print("1:发送消息")
            print("2:接收消息")
            print("0:退出系统")
            op=input("请输入操作编号:")
            if op == "1":
                send(udp_socket)
            elif op == "2":
                recv(udp_socket)
            elif op == "0":
                break
            else:
                print("输入错误请重新输入")
    
    if __name__=="__main__":
        main()

    同理引出tcp案例:

     服务端:

    import socket
    import threading
    import time
    
    def main():
        #tcp_sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        tcp_service()
    
    def tcp_service():  #服务端socket,接收客户端连接,把客户端发来的字符串加上hello发送回去
        tcp_sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        tcp_sock.bind(('127.0.0.1',9999))
        tcp_sock.listen(5)     #监听端口,传参指定等待连接的最大数量5
        print("wait for connect...")
        while True:
            sock,addr=tcp_sock.accept()     #建立连接
            t=threading.Thread(target=tcplink,args=(sock,addr))     #创建一个新线程去处理连接
            t.start
    
    def tcplink(sock,addr):     #为每个连接建立一个线程
        print("Accept new connection from %s:%s" %addr)
        sock.send(b'Hello')
        while True:
            data=sock.recv(1024)
            time.sleep(1)
            if not data or data.decode('utf-8') == 'exit':
                break
            sock.send(('Hello,%s!' % data.decode('utf-8')).encode('utf-8'))
        sock.close()
        print('Connection from %s:%s closed' %addr)
    
    if __name__=='__main__':
        main()

    客户端:

    import socket
    
    def main():
        test_link()
    
    def tcp_client():   #客户端socket,进行数据的发送与收集
        tcp_c= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        tcp_c.connect(('127.0.0.1',9999))
        tcp_c.send(b'GET / HTTP/1.1
    Host: www.sina.com.cn
    Connection: close
    
    ')  # 发送请求
    
        buffer = []
        while (True):
            d = tcp_c.recv(1024)
            if d:
                buffer.append(d)
            else:  # 一直接收数据,一次最多接收1024位字节;当接收数据为空时,接收完毕,退出循环
                break
        data = b''.join(buffer)
        tcp_c.close()
    
        header,html=data.split(b'
    
    ',1)   #将http头和html分离,http头打印出来,html保存在本地
        print(header.decode('utf-8'))
        with open('test html','wb') as f:
            f.write(html)
    
    def test_link():    #测试连接
        tcp_t= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        tcp_t.connect(('127.0.0.1',9999))
        print(tcp_t.recv(1024).decode('utf-8'))
        for data in [b'mike',b'bob',b'lili']:
            tcp_t.send(data)
            print(tcp_t.recv(1024).decode('utf-8'))
        tcp_t.send(b'exit')
        tcp_t.close
    
    
    if __name__=='__main__':
        main()
        
  • 相关阅读:
    解决 typedef void * POINTER_64 PVOID64; 问题
    短时间内快速获取随机数的方法
    怎样彻底重装IE
    在InstallShield中手动修改XML Files Changes
    Data, Privacy, & ECommerce ISDPE2010 Call for Papers
    DOS命令输出的重定向
    解决:Error spawning 'cmd.exe'
    wuapi 相关文件下载URL
    使用临界区 CRITICAL_SECTION 实现互斥
    修正 IPMSG 2.51 版本中的一点翻译错误
  • 原文地址:https://www.cnblogs.com/jinziguang/p/11864168.html
Copyright © 2011-2022 走看看