基于TCP的套接字
【1】方法简介
- tcp是基于链接的
- 必须先启动服务端
- 然后再启动客户端去链接服务端
- tcp服务端
server = socket() #创建服务器套接字
server.bind() #把地址绑定到套接字
server.listen() #监听链接
inf_loop: #服务器无限循环
conn = server.accept() #接受客户端链接
comm_loop: #通讯循环
conn.recv()/conn.send() #对话(接收与发送)
conn.close() #关闭客户端套接字
server.close() #关闭服务器套接字(可选)
- tcp客户端
client = socket() # 创建客户套接字
client.connect() # 尝试连接服务器
comm_loop: # 通讯循环
client.send()/client.recv() # 对话(发送/接收)
client.close() # 关闭客户套接字
【2】打电话模型
【1.0】基础版
- 服务端
# 先写服务端
# 打电话
import socket
# 【1】先有电话
server = socket.socket()
# 【2】电话要插卡
# ('ip','port')
IP = '127.0.0.1' # 本地的回环地址 / localhost
PORT = 8080
server.bind((IP, PORT))
# 【3】可能会接受到别人的电话
# 半连接池 :
server.listen(5)
# 【4】接电话
conn, addr = server.accept()
# print(f'conn :>>>> {conn}')
# print(f'addr :>>>> {addr}')
# # conn :>>>> <socket.socket fd=352, family=2, type=1, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 50851)>
# # addr :>>>> ('127.0.0.1', 50851)
# 【5】接受消息
# 参数 : 接收到的数据的大小
from_to_client_msg = conn.recv(1024)
from_to_client_msg = from_to_client_msg.decode('utf-8')
print(f'from_to_client_msg :>>>> {from_to_client_msg}')
# 【6】回复消息
# 传输的数据是二进制格式的数据
# send_msg = b'你好'
send_to_client_msg = '你好'
send_to_client_msg = send_to_client_msg.encode('utf-8')
conn.send(send_to_client_msg)
# 【7】挂断电话
conn.close()
# 【8】手机关机
server.close()
- 客户端
import socket
# 【1】有一部手机
client = socket.socket()
# 【2】接电话,知道别人的电话号
IP = '127.0.0.1'
PORT = 8080
client.connect((IP, PORT))
# 【3】发送消息
send_to_server_msg = f'我是客户端'
send_to_server_msg = send_to_server_msg.encode('utf-8')
client.send(send_to_server_msg)
# 【4】接受消息
from_server_msg = client.recv(1024)
# 二进制数据解码
from_server_msg = from_server_msg.decode('utf-8')
print(f'from_server_msg :>>>> {from_server_msg}')
# 【5】挂电话
client.close()
基础版模版
############ 服务端
# 导入模块
from socket import socket
# 创建socket对象
server = socket()
# 监听端口
IP = '127.0.0.1'
PORT = 9080
server.bind((IP, PORT))
# 监听连接对象个数
server.listen(5)
# 创建连接对象
conn, addr = server.accept()
# 通过连接对象接收数据 1kb = 1024 bytes
from_client_lsg = conn.recv(1024)
from_client_lsg = from_client_lsg.decode('utf8')
print(from_client_lsg)
# 回数据
send_to_client_msg = '我是服务端'
send_to_client_msg = send_to_client_msg.encode('utf8')
conn.send(send_to_client_msg)
# 关闭链接
conn.close()
# 关闭连接
server.close()
############ 客户端
from socket import socket
# 创建客户端对象
client = socket()
# 监听连接
# 监听端口
IP = '127.0.0.1'
PORT = 9080
client.connect((IP, PORT))
# 发送
send_to_server_msg = '我是客户端'
send_to_server_msg = send_to_server_msg.encode('utf8')
client.send(send_to_server_msg)
# 接收
from_server_msg = client.recv(1024)
from_server_msg = from_server_msg.decode('utf8')
print(from_server_msg)
# 关闭链接
client.close()
【2.0】循环版
- server
# 先写服务端
# 打电话
import socket
# 【1】先有电话
server = socket.socket()
# 【2】电话要插卡
# ('ip','port')
IP = '127.0.0.1' # 本地的回环地址 / localhost
PORT = 8060
server.bind((IP, PORT))
# 【3】可能会接受到别人的电话
# 半连接池 :
server.listen(5) # 限制客户端数量
while True:
# 【4】接电话
conn, addr = server.accept()
# 【5】接受消息
from_to_client_msg = conn.recv(1024)
from_to_client_msg = from_to_client_msg.decode('utf-8')
print(f'from_to_client_msg :>>>> {from_to_client_msg}')
# 【6】回复消息
# 传输的数据是二进制格式的数据
# send_msg = b'你好'
while True:
send_to_client_msg = input("请输入需要发送的消息 :>>>> ").strip()
if not send_to_client_msg:
print(f'当前不能为空!请重新输入!')
continue
send_to_client_msg = send_to_client_msg.encode('utf-8')
conn.send(send_to_client_msg)
break
# 【7】挂断电话
conn.close()
# 【8】手机关机
server.close()
- client
import socket
while True:
# 【1】有一部手机
client = socket.socket()
# 【2】接电话,知道别人的电话号
IP = '127.0.0.1'
PORT = 8060
client.connect((IP, PORT))
# 【3】发送消息 --- 发送的消息不能为空
send_to_server_msg = input("请输入发送的消息 :>>>> ").strip()
if not send_to_server_msg:
print(f'当前不能为空!请重新输入!')
continue
send_to_server_msg = send_to_server_msg.encode('utf-8')
client.send(send_to_server_msg)
# 【4】接受消息
from_server_msg = client.recv(1024)
# 二进制数据解码
from_server_msg = from_server_msg.decode('utf-8')
print(f'from_server_msg :>>>> {from_server_msg}')
# 【5】挂电话
client.close()
循环版模版
############ 客户端
# 创建对象
from socket import socket
while True:
client = socket()
# 创键连接
client.connect(('127.0.0.1', 9696))
# 发送消息
send_msg = input("请输入消息 :>>>> ").strip()
if not send_msg: continue
client.send(send_msg.encode('utf-8'))
if send_msg == 'q':
client.close()
break
# 接收消息
msg = client.recv(1024)
print(msg.decode('utf8'))
############ 服务端
from socket import socket
server = socket()
server.bind(('127.0.0.1', 9696))
server.listen(5)
while True:
conn, addr = server.accept()
# 先接受
msg = conn.recv(1024)
msg = msg.decode('utf8')
print(f'msg:>>>{msg}')
if msg == 'q':
conn.close()
break
# 再发送
while True:
send_msg = input("发送的消息 :>>>> ").strip()
if not send_msg: continue
conn.send(send_msg.encode('utf8'))
break
server.close()
空数据的处理
- TCP协议是水流式协议:传入的数据不能为空,因为水是一直流的,在传输过程中不会对数据进行操作
- UDP协议是数据报协议:传入的数据可为空,在传输过程中UDP会对数据进行内部的拼接和处理
断开链接的影响
- TCP协议是水流式协议:在建立链接过程中,服务端和客户端的链接是一直存在的,断开一方都会对另一方造成影响
- UDP协议是数据报协议:在建立链接过程中,是通过解析对方数据中的ip和端口,再向另一方返回数据的,所以一方发生问题并不会影响到另一方