网络编程:TCP协议: 三次握手,四次挥手,socket套接字通信:,粘包问题subprocess模块,struct模块

网络编程:TCP协议: 三次握手,四次挥手,socket套接字通信:,粘包问题subprocess模块,struct模块

1.TCP协议: 三次握手,四次挥手

TCP协议  ---> 传输协议:基于端口工作的。
TCP协议建立双向通道。

三次握手, 建连接:

1:客户端向服务端发送建立连接的请求
2:服务端返回收到请求的信息给客户端,并且发送往客户端建立连接的请求
3:客户端接收到服务端发来的请求,返回接成功给服务端,完成双向连接

C ----> S
C <---- S

三次握手
C ---> S:
1.C先发送请求给S,S接收到请求反馈一个确认收到消息返回给C,建立了C--->S的通道。
2.S并将往C建立通道的请求发送给C,C接收到请求反馈一个确认收到消息返回给S,建立了S-->C的通道。
3.此时双向通道建立好了。
反馈机制:
客户端往服务端发送请求,服务端必须返回响应,告诉客户端收到请求了,并且将服务端的数据一并返回给客户端。
C-->S: 一次请求,必须有一次响应。
缺点:
- 洪水攻击:
指的是通过伪造大量的请求,往对方服务器发送请求,
导致对方服务器响应跟不上,以至于瘫痪。
linux系统有个参数可以限制。

- 半连接池listen: 限制用户在同一个时间段内的访问数量。

四次挥手, 断开连接。

1:客户端向服务端发送断开连接的请求
2:服务端返回收到请求的信息给客户端
3:服务端确认所有数据接收完成以后,再发送同意断开连接的请求给客户端
4:客户端返回收到断开连接的请求,给服务端。


C ----> S
1.C先发送断开连接的请求给S, S接收到请求反馈一个确认收到消息返回给C,断开了C--->S的通道。
2.S检查是否还有数据没有发送完,确认数据发送完毕后,再向C端发送断开连接的请求。
3.C接收到请求反馈一个确认收到消息返回给S,断开S--->C的通道。
4.断开双向通道。

2.socket套接字通信:

什么是socket?

socket是一个模块, 又称套接字,用来封装 互联网协议(应用层以下的层)。

为什么要有socket?

socket可以实现 互联网协议应用层以下的层的工作。
- 提高开发效率

怎么使用socket?

import socket
            写socket套接字:
                Client
                Server

subprocess模块

1.可以帮你通过代码执行操作系统的终端命令。

​ 2.并且返回终端执行命令后的结果。

client

'''
启动服务端后再启动客户端
'''
import socket

# 买手机
client = socket.socket()

# 拨号
client.connect(
    # 客户端的ip与port必须与服务端一致
    ('127.0.0.1', 9527)
)

print('client is running...')

# 必须发送bytes类型的数据
# client.send('hello'.encode('utf-8'))
# 讲话给对方听
client.send(b'hello im client...')
data = client.recv(1024)
print(data)

client.close()

服务端

'''
注意:
    客户端先一次发送,服务端得先一次接受,再发送消息。
'''
import socket

# 买手机
server = socket.socket()

# 绑定手机卡
server.bind(
    # 相当于手机号码
    # 127.0.0.1 == localhost 本机回环地址
    # 单机测试下: 127.0.0.1
    ('127.0.0.1', 9527)
)

# 半连接池
server.listen(5)  # 最多5个人坐椅子, 实际上==6

print('server is running...')

# 等待电话接入
# conn: 指的是服务端往客户端的管道
conn, addr = server.accept()

# 接听对方讲话的内容
# data客户端发送过来的消息
data = conn.recv(1024)  # 可接受一次1024bytes的数据
print(data)

# 服务端往客户端发送消息
conn.send(b'hi im server')


# 挂电话
conn.close()



最终版本

client

'''
启动服务端后再启动客户端
'''
import socket

# 买手机
client = socket.socket()

# 拨号
client.connect(
    # 客户端的ip与port必须与服务端一致
    ('127.0.0.1', 9527)
)

print('client is running...')

# 必须发送bytes类型的数据
# 讲话给对方听
while True:
    send_data = input('客户端>>>:')
    client.send(send_data.encode('utf-8'))
    data = client.recv(1024)

    if data.decode('utf-8') == 'q':
        break

    if len(data) == 0:
        break

    print(data.decode('utf-8'))

client.close()



server

'''
注意:
    客户端先一次发送,服务端得先一次接受,再发送消息。
'''
import socket
# 买手机
server = socket.socket()

# 绑定手机卡
server.bind(
    # 相当于手机号码
    # 127.0.0.1 == localhost 本机回环地址
    # 单机测试下: 127.0.0.1
    ('127.0.0.1', 9527)
)
# 半连接池
server.listen(5)  # 最多5个人坐椅子, 实际上==6
print('server is running...')

# 循环实现可接受多个用户访问
while True:
    # 等待电话接入 ---> 接入客户端
    # conn: 指的是服务端往客户端的管道
    conn, addr = server.accept()
    print(addr)

    # 循环实现循环通信
    while True:
        try:  # 监听代码块是否有异常出现
            # 接听对方讲话的内容
            # data客户端发送过来的消息
            data = conn.recv(1024)  # 可接受一次1024bytes的数据

            if len(data) == 0:
                break
            if data.decode('utf-8') == 'q':
                break
            print(data.decode('utf-8'))
            send_data = input('服务端>>>:')
            # 服务端往客户端发送消息
            conn.send(send_data.encode('utf-8'))

        # 捕获异常信息,并打印  # e: 报错信息
        except Exception as e:
            print(e)
            break

    # 挂电话
    conn.close()

3.粘包问题

服务端第一次发送的数据,客户端无法精确一次性接受完毕。
下一次发送的数据与上一次数据粘在一起了。
 
1.无法预测对方需要接受的数据大小长度。
2.多次连续发送数据量小、并且时间间隔短的数据一次性打包发送。
 
TCP协议特性:
tcp是一个流式协议,会将多次连续发送数据量小、并且时间间隔短的数据一次性打包发送。


缺点:数据不安全

解决粘包问题

- struct
            - Client:
                - 1.制作报头(i: 4bytes),先发送报头。
                - 2.发送真实数据

            - Server:
                - 1.先接收报头,解包获取真实数据长度
                - 2.再根据真实数据长度接收真实数据

        - send_dic:
            {
   
                'movie_name': '某某的故事',
                'movie_size': 1000000,
                'md5': md5字符串
            }

            - 摘要:
                - 摘要一样数据就一定一样

                import hashlib
                md5 = hashlib.md5()

                
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值