ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

socket套接字简介

2022-04-16 00:31:07  阅读:128  来源: 互联网

标签:socket 简介 len print msg 接字 服务端 客户端


目录

一.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,简介,len,print,msg,接字,服务端,客户端
来源: https://www.cnblogs.com/xwkg/p/16151664.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有