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.断开双向通道。
socket是一个模块, 又称套接字,用来封装 互联网协议(应用层以下的层)。
socket可以实现 互联网协议应用层以下的层的工作。
- 提高开发效率
import socket
写socket套接字:
Client
Server
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()
服务端第一次发送的数据,客户端无法精确一次性接受完毕。
下一次发送的数据与上一次数据粘在一起了。
1.无法预测对方需要接受的数据大小长度。
2.多次连续发送数据量小、并且时间间隔短的数据一次性打包发送。
TCP协议特性:
tcp是一个流式协议,会将多次连续发送数据量小、并且时间间隔短的数据一次性打包发送。
缺点:数据不安全