一 基础知识
在进行代码实现前,先简单介绍下TCP,UDP,Socket等基础知识。
首先要了解下socket(套接字),我们可以通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。
另外在通讯中,我们经常使用TCP和UDP,TCP,UDP属于传输层的连接,他们之间区别是TCP是面向链接的,他的连接需要经过三次握手;而UDP传送数据前并不与对方建立连接。所以一般说TCP比UDP安全,但是UDP比TCP实时。
HTTP属于应用层的协议,只有连接把数据进行传输,但是没有一个协议的话我们不知道传输的到底是什么东西,所以需要一个应用层的HTTP协议(超文本传送协议Hypertext Transfer Protocol )。TCP是底层通讯协议,定义的是数据传输和连接方式的规范;HTTP是应用层协议,定义的是传输数据的内容的规范;
我们有了连接,还需要一个对外的变成接口,这就是本文要介绍的Socket套接字了。Sockert编程接口就是为了让我们更方便的使用协议栈。
具体的介绍可以参考:
TCP和UDP区别以及HTTP协议
https://segmentfault.com/a/1190000014044351
Socket连接与HTTP连接
https://cloud.tencent.com/developer/article/1124905
二 代码示例
下面我们直接使用python的Socket进行编程,简单实现一个客户端发送请求,服务端收到请求后返回一个json的示例。
需要用到的库就是
import socket
服务端代码
服务端主要做的事情
- 创建套接字:socket.socket()
- 绑定IP和端口:socket.bind()
- 开始tcp监听socket.listen()
- 接受tcp连接,等待数据:socket.accept()
- 接收数据:socket.recv()
- 发送处理数据:socket.sendall()
- 关闭套接字:socket.close()
其中recv和send是bytes类型,所以如果是字符串或者json格式需要进行下转换。因为项目中多使用json格式,所以本文也以收到str,返回json的形式编写示例。
服务端详细代码如下:
代码语言:javascript复制import json
import socket
HOST = '127.0.0.1'
PORT = 8000
ADDR = (HOST,PORT)
def start_server():
# 创建套接字:AF_INET--使用ipv4地址族 SOCK_STREAM--用流式套接字
svr_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
svr_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 绑定host:port
svr_socket.bind(ADDR)
# setblocking 0--非阻塞模式 ,1--阻塞模式 默认为1
svr_socket.setblocking(1)
# 开始监听TCP传入连接
svr_socket.listen(5)
# 返回新的套接字和客户端地址
client_socket, addr = svr_socket.accept()
client_socket.settimeout(20.0)
# 接收数据,这里先接收数据长度(需要和客户端协商发送格式,是否是len data的形式),可以不用这一步
data_len = client_socket.recv(4)
length = int.from_bytes(data_len, byteorder="big")
# 接收的具体数据,这里也可以设置一个较大缓冲区
data = client_socket.recv(length)
print("rev client data", data)
# 返回给客户端数据,设置为一个json
json_msg ={"key":"id","val": 123}
str_msg = json.dumps(json_msg)
# 字符串要转为bytes传输
client_socket.sendall(str_msg.encode())
# 关闭套接字
client_socket.close()
if __name__ == '__main__':
start_server()
客户端代码
服务端主要做的事情
- 创建套接字:socket.socket()
- 打开tcp连接:socket.connect()
- 发送请求数据:socket.sendall()
- 接收服务端数据:socket.recv()
- 关闭套接字:socket.close()
完整代码:
代码语言:javascript复制import json
import socket
HOST = '127.0.0.1'
PORT = 8000
ADDR = (HOST,PORT)
def start_client():
# 创建套接字
_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 打开tcp连接
_socket.connect(ADDR)
msg = "msg from client"
length = len(msg)
buf = length.to_bytes(4, byteorder="big")
# 发送请求数据 len data格式
_socket.sendall(buf msg.encode())
# 接收服务端返回数据
data = _socket.recv(1024)
msg = json.loads(data)
print("client get json", msg)
# 关闭套接字
_socket.close()
if __name__ == '__main__':
start_client()