何谓socket
计算机,顾名思义即是用来做计算。因而也需要输入和输出,输入需要计算的条件,输出计算结果。这些输入输出可以抽象为I/O(input output)。
Unix的计算机处理IO是通过文件的抽象。计算机不同的进程之间也有输入输出,也就是通信。因此这这个通信也是通过文件的抽象文件描述符来进行。
在同一台计算机,进程之间可以这样通信,如果是不同的计算机呢?网络上不同的计算机,也可以通信,那么就得使用网络套接字(socket)。socket就是在不同计算机之间进行通信的一个抽象。他工作于TCP/IP协议中应用层和传输层之间的一个抽象。如下图:
socket.jpg
服务器通信
socket保证了不同计算机之间的通信,也就是网络通信。对于网站,通信模型是客户端服务器之间的通信。两个端都建立一个socket对象,然后通过socket对象对数据进行传输。通常服务器处于一个无线循环,等待客户端连接:
socket3.jpg
socket 通信实例
socket接口是操作系统提供的,调用操作系统的接口。当然高级语言一般也封装了好用的函数接口,下面用python代码写一个简单的socket服务端例子:
server.py
importsocketHOST ='localhost'# 服务器主机地址PORT =5000# 服务器监听端口BUFFER_SIZE =2048# 读取数据大小# 创建一个套接字sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 绑定主机和端口sock.bind((HOST, PORT))# 开启socket监听sock.listen(5)print'Server start, listening {}'.format(PORT)whileTrue:# 建立连接,连接为建立的时候阻塞conn, addr = sock.accept()whileTrue:# 读取数据,数据还没到来阻塞data = conn.recv(BUFFER_SIZE)iflen(data):print'Server Recv Data: {}'.format(data) conn.send(data)print'Server Send Data: {}'.format(data)else:print'Server Recv Over'breakconn.close()sock.close()
client.py
importsocketHOST ='localhost'PORT =5000BUFFER_SIZE =1024# 创建客户端套接字sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 连接到服务器sock.connect((HOST, PORT))try: message ="Hello"# 发起数据给服务器sock.sendall(message) amount_received =0amount_expected = len(message)whileamount_received < amount_expected:# 接收服务器返回的数据data = sock.recv(10) amount_received += len(data)print'Client Received: {}'.format(data)exceptsocket.errno, e:print'Socket error: {}'.format(e)exceptException, e:print'Other exception: %s'.format(e)finally:print'Closing connection to the server'sock.close()
TCP 三次握手
python代码写套接字很简单。传说的TCP三次握手又是如何体现的呢?什么是三次握手呢?
第一握:首先客户端发送一个syn,请求连接,
第二握:服务器收到之后确认,并发送一个 syn ack应答
第三握:客户端接收到服务器发来的应答之后再给服务器发送建立连接的确定。
用下面的比喻就是
C:约么?
S:约
C:好的
约会
这样就建立了一个TCP连接会话。如果是要断开连接,大致过程是:
tcp.png
上图也很清晰的表明了三次握手的socket具体过程。
客户端socket对象connect调用之后进行阻塞,此过程发送了一个syn。
服务器内核完成三次握手,即发送syn和ack应答。
客户端socket对象收到服务端发送的应答之后,再发送一个ack给服务器,并返回connect调用,建立连接。
服务器socket对象接受客户端最后一次握手确定ack建立连接。
此时服务端调用accept,则从连接队列中将之前建立的连接取出返回。
至此,客户端和服务器的socket通信连接建立完成,剩下的就是两个端的连接对象收发数据,从而完成网络通信。
文中图片来源网络
更多细节,可以阅读TCP握手与socket通信细节