• 操作socket笔记


    网络编程

      1.tcp协议

    #tcpserver
    #单纯一对一发
    tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 创建tcp套接字 参数(ipv4,tcp)
    tcp.bind(('127.0.0.1', 8000))  # 为服务端创建本地绑定信息 参数为元组 '' 代表绑定本地 端口要求int类型
    tcp.listen()  # listen(n)监听模式 默认套接字变为被动等待为触发
    client_socket, clent_socket_address = tcp.accept()  # 阻塞 等待客户端连接 返回值为元组 (socket套接字,客户端的地址)
    while True:
        if client_socket:
            print("连接成功!")
            print("client_socket:", client_socket)
            print("clent_socket_address:", clent_socket_address)
            recv = client_socket.recv(1024)  # 服务端 接收 1024为接收的最大数据大小
            print("-->:", recv.decode('utf-8'))
            client_socket.send('这里是rainbol的客户端请求'.encode('utf-8'))  # 服务端回复,服务端发送时需要bytes类型
    client_socket.close()
    tcp.close()
    #tcpclient
    #客户端
    tcp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    tcp_socket.connect(('127.0.0.1',8000))
    while True:
        data = input('-->:')
        tcp_socket.send(data.encode('utf-8'))#把字符串转成二进制,并把发送data
        recv_data = tcp_socket.recv(1024)# 接收服务端返回的消息
        print('-->%s'%recv_data.decode('utf-8'))
    tcp_socket.close()

      粘包问题

    #client
    '''
    黏包现象:tcp传输过程中基本传输1500字节后就要进行分包处理,发送端默认进行拆包,接收端进行合包 一种是因为发送数据包时,每次发送的包小,因为系统进行优化算法,就将两次的包放在一起发送,减少了资源的重复占用。多次发送会经历多次网络延迟,一起发送会减少网络延迟的次数。因此在发送小数据时会将两次数据一起发送,而客户端接收时,则会一并接收。#即出现多次send会出现黏包 第二种是因为接收数据时,又多次接收,第一次接收的数据量小,导致数据还没接收完,就停下了,剩余的数据会缓存在内存中,然后等到下次接收时和下一波数据一起接收。 为了校验数据的完整 ''' '解决黏包:本质是因为我们在传输时不知道该数据包到底多大,取决于服务端和客户端相互协定如下方式' import socket import struct soc = socket.socket() soc.connect(('127.0.0.1',9000)) msg = b'hello' msg_len = struct.pack('i',len(msg))#反正粘包现象,使用struct模块发送tcp数据时一开始告诉服务器发送字节数的大小,struct的i参数可以把8位数字节数以4个字节数类似'/SAD/sadsa/sad/sadasd'先发送给服务端 soc.send(msg_len) soc.send(msg) msg = b'world' msg_len = struct.pack('i',len(msg)) soc.send(msg) soc.close()
    #server
    import socket
    import struct
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind(('127.0.0.1',9000))
    server.listen()
    client_socket, clent_socket_address = server.accept()
    get_lens = client_socket.recv(4)#先拿4个字节
    get_size = struct.unpack('i',get_lens)[0] #拿到数据长度
    msg1 = client_socket.recv(get_size) #再接收所有数据
    print(msg1)
    
    get_lens = client_socket.recv(4)#先拿4个字节
    get_size = struct.unpack('i',get_lens)[0] #拿到数据长度
    msg2 = client_socket.recv(get_size)
    print(msg2)

      2.udp协议

    #server
    import socket
    soc = socket.socket(type=socket.SOCK_DGRAM)#默认tcp如果变成udp要加SOCK_DGRAM
    soc.bind(('127.0.0.1',9000))
    ret,client_addr = soc.recvfrom(1024)
    print(ret)
    soc.sendto(b'ok',client_addr)#返回给客户端接收成功
    soc.close()
    #client
    import socket
    soc = socket.socket(type=socket.SOCK_DGRAM)
    ret = soc.sendto(b'helloworld',('127.0.0.1',9000)) #参数一:想要发送的byte字节,参数二:想要发送给谁的地址
    msg = soc.recv(1024)#接收服务端返回结果
    print(msg)
    soc.close()
  • 相关阅读:
    034.Python的__str__,__repr__,__bool__ ,__add__和__len__魔术方法
    033.Python的__del__析构方法he__call__方法
    032.Python魔术方法__new__和单态模式
    python3使用tabulate漂亮的打印数据
    在Linux真正有效的调节鼠标速度!
    RouterOS上实现内网DNS劫持
    使用grease monkey强力清除搜索结果页的广告
    centos 6.5 apache下配置python cgi 并解决中文乱码
    python的缩进语法不是一种好的设计
    让npm默认使用taobao镜像源
  • 原文地址:https://www.cnblogs.com/RainBol/p/10150215.html
Copyright © 2020-2023  润新知