socket抽象层位于应用层和传输层之间,是对传输层TCP协议和UDP协议的封装,可以让我们无需关心复杂的TCP协议和UDP协议,直接使用socket提供的函数就可以进行网络编程。


图片来源:https://www.cnblogs.com/Andya/p/7272462.html
客户端步骤:
-
socket()
创建客户端套接字 -
connect()
尝试连接服务器 - 进行
write()
或者read()
操作 close()
服务端步骤:
-
socket()
创建服务器套接字 -
bind()
把地址绑定到套接字 -
listen()
监听链接
inf_loop: # 服务器无限循环
cs = ss.accept() # 接受客户端链接
comm_loop: # 对接收到的链接 进行通讯循环
cs.recv()或者cs.send() # 与客户端对话
cs.close() # 关闭客户端套接字
ss.close() # 关闭服务器套接字
1.基础版
服务端实现:
# 服务端
import socket
# 创建服务器套接字 基于网络类型通信而非文件类型 SOCK_STREAM表示TCP协议 流式通信
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定ip地址和端口到套接字 使用元组
server.bind(('127.0.0.1', 8000))
# 监听连接 最大监听数 设置backlog连接池 设置大了可以尽可能的防止syn洪水攻击
server.listen(5)
# 等待 返回建立的链接和地址 收到消息前会一直等待 不执行下面的代码,收到消息后才会向下执行
connection, addr = server.accept()
# 收到的消息 最大1024字节
reveiveMsg = connection.recv(1024)
# 发送消息
connection.send(reveiveMsg)
connection.close()
server.close()
客户端实现:
# 客户端
import socket
# 建立socket 基于网络类型通信而非文件类型 SOCK_STREAM表示TCP协议 流式通信
customer = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定ip地址和端口 使用元组
customer.connect(('127.0.0.1', 8000))
customer.send('hello'.encode('utf-8')) # 等同于bytes(data,encoding='utf-8')
data = customer.recv(1024)
print("客户端收到的消息是", data)
2.进化版
服务端循环处理消息:
服务端要做防崩溃处理,来防止客户端断开连接后抛出异常
# import socket
from socket import *
ip_port=('127.0.0.1',8080)
back_log=5
buffer_size=1024
tcp_server=socket(AF_INET,SOCK_STREAM)
tcp_server.bind(ip_port)
tcp_server.listen(back_log)
while True:
print('服务端开始运行了')
conn,addr=tcp_server.accept() #服务端阻塞
print('双向链接是',conn)
print('客户端地址',addr)
while True:
try:
data=conn.recv(buffer_size)
print('客户端发来的消息是',data.decode('utf-8'))
conn.send(data.upper())
except Exception:
break
conn.close()
tcp_server.close()
客户端循环发送:
客户端要做发送消息检测,如果是空消息,会导致应用层从内核内存中获取数据循环等待假死
# import socket
from socket import *
ip_port=('127.0.0.1',8080)
back_log=5
buffer_size=1024
tcp_client=socket(AF_INET,SOCK_STREAM)
tcp_client.connect(ip_port)
while True:
msg=input('>>: ').strip()
if not msg:continue
tcp_client.send(msg.encode('utf-8'))
print('客户端已经发送消息')
data=tcp_client.recv(buffer_size)
print('收到服务端发来的消息',data.decode('utf-8'))
tcp_client.close()
提示
碰到端口占用错误解决方法:
- 在socket配置增加重用ip和端口
在bind前增加:
tcp_client.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
- 另一种方法是修改内核

网友评论