socket套接字简介

2022/4/16 6:25:07

本文主要是介绍socket套接字简介,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

目录
  • 一.socket
  • 二..socket模块
    • 1.服务端
    • 2.客户端
  • 三.通讯循环
  • 四.优化代码以及链接循环
  • 六.黏包问题
  • 解决黏包模块

一.socket

1.socket套字节是一门:技术
2.socket模块:提供了快捷方式,不需要自己处理数据
3.socket:底层原理,与框架是被封装过的

二..socket模块

"""
如果每次编写C/S架构程序,都需要使用OSI七层架构去编写,很复杂,所以就用到了socket模块,这个模块就是利用了socket套接字技术
"""
# 我们知道编写C/S架构设计的时候,是使用:C(客户端),S(服务端)

1.服务端

    import socket


    server = socket.socket()                   # 1.联网协议赋予变量名
    # 括号内不写参数默认就是基于网络的遵循TCP协议的套接字

    server.bind(('127.0.0.1', 8101))           # 2.选择地址 与端口
    # 127.0.0.1本计算机的回环地址,只有本机可以访问,8101端口号,一般是8000以后

    server.listen(5)                           # 3.成功链接网络
    # 连接池可以拥有5个用户连接,参数5代表了最大用户量

    sock, addr = server.accept()               # 4.等待用户连接.没有用户连接就原地等待
    # sock 表示接受信息,addr 表示客户端的地址

    while True:
        data = sock.recv(1024)                 # 5.用来接受服务端信息
        # 1024 字节数

        msg = input('您回复的消息>>>:').strip() # 6.采用了自定义方法回复用户信息

        if len(msg) == 0:
            # 判断回复消息数量不能为0
            msg = '自动回复'

        sock.send(msg.encode('utf8'))
        # 因为是基于网络发送,所以要转换bytes类型二进制

        sock.close()                           # 7.停止当前客户端对话

        server.close()                         # 8.停止所有链接服务器并关闭

注:和游戏一样,服务器崩溃的话用户在玩游戏会自动断开,所以启动的话启动肯定是先启动服务端

2.客户端

import socket
# 这是客户端
client = socket.socket()                       # 1.同服务端一样
# 使用TCP协议套接字
client.connect(('127.0.0.1', 8101))            # 2.根据服务器第地址和端口进行链接
# 链接到服务器端
msg = input('请输入你要说的话>>:').strip()      # 3.给服务端口发送自定义消息

client.send(msg.encode('utf8'))                # 4.基于网络需要进行编码

data = client.recv(1024)                       # 5.接收返回的服务端字节数进行匹配
   
print(data.decode('utf8'))                     # 6.通过解码打印出服务端回复的消息

client.close()                                 #  7.关闭客户链接端口

服务端口(recv)与客户端(send)
接受与发送必须一边一个不然就出现都在等待尴尬情况

三.通讯循环

1.回复与发送消息可以是固定的也可以是自定义的
input:自定义用户交互

2.也可以通过循环方式进行不限交流
while True: 循环发送,接收

服务端
while True:
    data = sock.recv(1024)  # 匹配字节
    print(data.decode('utf8'))
    msg = input('请回复消息>>>:').strip()
    sock.send(msg.encode('utf8'))  # 匹配成功进行回复
客户端
while True:
    msg = input('请输入你需要发送的消息>>>:').strip()
    client.send(msg.encode('utf8'))  # 给服务端发送消息
    data = client.recv(1024)  # 接收服务端回复的消息
    print(data.decode('utf8'))

"""客户端要先发话,玩游戏出现问题一定是你去找客服去沟通"""

四.优化代码以及链接循环

1.发送消息不能为空
# 通过判断len字符长度不能为0否则结束从新运行

2.反复重启服务器端可能会报错
# >>>:address in use 苹果系统报错频繁
# windows 报错较少
# 原因是mac在重启服务器的时候,端口未被释放稀释,会导致服务器地址冲突等.

 from socket import SOL_SOCKET,SO_REUSEADDR 
 server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) # 在bind前加

3.链接循环
如果是windows 客户端异常退出之后服务端会直接报错
  	处理方式
  异常处理
如果是mac或linux 服务端会接收到一个空消息
  	处理方式
  len判断
'客户端如果异常断开 服务端代码应该重新回到accept等待新的客户'
# 五.半链接池
```python
listen(5)
# 打一个比喻 你给10086打电话人工客服反应问题.比如就只有一个人工客服,那么其他人打电话是占线,'尊敬的用户您好,客服马上将在10~0秒时间内接听' 那么你等的这个时间 就是服务器端口与你(客户端)半连接状态,你听的可能是0~10秒 其他就是正忙稍后等待,半连接池就是相当于等待时间
都要排队(5) 就是最多排队个数,超出就选择其他业务

六.黏包问题

黏包问题:在于TCP协议传输中存在的问题,UDP倒是不会,TCP进行传输数据同时会将我服务端所(说的话,接收的话)丢到一个缓存区,缓存大小未知.
'1024是默认字节数,接收和发送的最大字节数'
在读取的时候因为未知大小所以会导黏包

解决黏包模块

struct模块
可以精准的获取数据的大小
import struct

data1 = 'hello world!'
print(len(data1))  
# 结果,12位
res1 = struct.pack('i', len(data1))  # 第一个参数是格式 写i就可以了
print(len(res1)) 
# 4位
ret1 = struct.unpack('i', res1)
print(ret1)  
# (12,) 位元组形式


data2 = 'hello baby baby baby baby baby baby baby baby'
print(len(data2))  
# 结果,45位
res2 = struct.pack('i', len(data2))
print(len(res2))  
# 4位
ret2 = struct.unpack('i', res2)
print(ret2)  
# (45,) 元组形式

"""
1.可以推断出pack可以将任意长度元素打包成功固定(4)位 
2.可以推断出unpack可以将被解除打包还原打包前的位数
"""



这篇关于socket套接字简介的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程