socket编程相关阐述

一、socket初识

①服务端

import socket

server = socket.socket()
server.bind(('127.0.0.1', 8080))
server.listen(5)  # 半连接池

conn, addr = server.accept()   # 待机等待接听电话

data = conn.recv(1024)  # 接听别人说话,只接收1024字节
print(data)
conn.send(b'hello girl')  # 跟别人说话

conn.close()   # 关闭通信连接
server.close() # 关闭服务端

②客户端

import socket

client = socket.socket()
client.connect(('127.0.0.1', 8080))

client.send(b'hello how much?')
data = client.recv(1024)
print(data)

client.close()

二、通信循环

①服务端

服务端:
有固定的ip和port
24小时不间断提供服务

import socket

server = socket.socket()
server.bind(('127.0.0.1', 8080))
server.listen(5)

conn, addr = server.accept()

while True:
    try:
        data = conn.recv(1024)
        if len(data) == 0:break
        print(data)
        conn.send(data.upper())
    except ConnectionResetError:
        break

conn.close()
server.close()

②客户端

import socket

client = socket.socket()
client.connect(('127.0.0.1', 8080))

while True:
    msg = input('>>>:').encode('utf-8')
    if len(msg) == 0: continue
    client.send(msg)
    data = client.recv(1024)
    print(data)

三、链接循环

①服务端

import socket

server = socket.socket()
server.bind(('127.0.0.1', 8080))
server.listen(5)

while True:
    conn, addr = server.accept()

    while True:
        try:
            data = conn.recv(1024)
            if len(data) == 0:break
            print(data)
            conn.send(data.upper())
        except ConnectionResetError:
            break

    conn.close()
server.close()

②客户端

import socket

client = socket.socket()
client.connect(('127.0.0.1', 8080))

while True:
    msg = input('>>>:').encode('utf-8')
    if len(msg) == 0: continue
    client.send(msg)
    data = client.recv(1024)
    print(data)

四、粘包问题的产生

1、粘包问题

  接收方:我不知道我要接收的数据的总长度

  发送方:由于tcp协议的内部优化算法 会将数据量比较小的并且时间间隔比较短的数据一次性打包发送

2、如何解决

  ①发送数据直接先告诉对方数据量的大小

  ②利用struct模块定制我们自己的消息传输协议

3、最终版本解决粘包问题

  客户端:

    ①制作字典报头

    ②发送报头

    ③再发送字典

    ④再发你的真实数据

  服务端:

    ①先收4个长度的报头

    ②解析报头,获取字典长度

    ③接收字典(反序列化) ——>> 获取字典里面所有信息

    ④接收真实数据

五、TCP协议特点:会将数据量比较小的并且时间间隔比较短的数据一次性打包发送

①服务端

import socket

server = socket.socket()
server.bind(('127.0.0.1',8088))
server.listen(5)  # 半连接池

conn,addr = server.accept()
data = conn.recv(5)   # 指定收到数据量的大小为5个,如果不指定,还是1024,就会出现粘包现象
print(data)      # b'hello'

data = conn.recv(5)
print(data)      # b'hello'

data = conn.recv(4)
print(data)      # b'hell'

②客户端

import socket

client = socket.socket()
client.connect(('127.0.0.1',8088))

client.send(b'hello')
client.send(b'hello')
client.send(b'hello')

六、struct模块

import struct

data = 'dfsafsagdsfgfafsdafsdafafryuio'

# 服务端
res = struct.pack('i', len(data))     # 打包:把一个数据打包为长度固定为4
print(len(res))   # 4
print(res)        # b'x1ex00x00x00'

# 客户端
ret = struct.unpack('i', res)[0]      # 解包:数据真实长度
print(ret)        # 30
原文地址:https://www.cnblogs.com/zhangguosheng1121/p/10796795.html