一文读懂Socket通信原理( 二 )


data = https://www.isolves.com/it/wl/zs/2020-03-07/conn.recv(1024)
print('Get value ' + data, end='nn')
if not data:
print('Exit Server', end='nn')
break
conn.sendall('OK') # 返回数据
except socket.timeout: # 建立连接后 , 该连接在设定的时间内没有数据发来 , 就会引发超时
print('Time out')
conn.close() # 当一个连接监听循环退出后 , 连接可以关掉
sock.close()conn, addr = sock.accept()
调用accept()时 , Socket会进入“waiting”状态 。客户请求连接时 , 方法建立连接并返回服务器 。accept()返回一个含有两个元素的元组(conn, addr) 。第一个元素conn是新的Socket对象 , 服务器必须通过它与客户通信;第二个元素addr是客户的IP地址及端口 。
data = https://www.isolves.com/it/wl/zs/2020-03-07/conn.recv(1024)
接下来是处理阶段 , 服务器和客户端通过send()和recv()通信(传输数据) 。
服务器调用send() , 并采用字符串形式向客户发送信息 , send()返回已发送的字符个数 。
服务器调用recv()从客户接收信息 。调用recv()时 , 服务器必须指定一个整数 , 它对应于可通过本次方法调用来接收的最大数据量 。recv()在接收数据时会进入“blocked”状态 , 最后返回一个字符串 , 用它表示收到的数据 。如果发送的数据量超过了recv()所允许的 , 数据会被截短 。多余的数据将缓冲于接收端 , 以后调用recv()时 , 多余的数据会从缓冲区删除(以及自上次调用recv()以来 , 客户可能发送的其它任何数据) 。传输结束 , 服务器调用Socket的close()关闭连接 。
TCP三次握手的Socket过程:

一文读懂Socket通信原理

文章插图
  • 服务器调用socket()、bind()、listen()完成初始化后 , 调用accept()阻塞等待;
  • 客户端Socket对象调用connect()向服务器发送了一个SYN并阻塞;
  • 服务器完成了第一次握手 , 即发送SYN和ACK应答;
  • 客户端收到服务端发送的应答之后 , 从connect()返回 , 再发送一个ACK给服务器;
  • 服务器Socket对象接收客户端第三次握手ACK确认 , 此时服务端从accept()返回 , 建立连接 。
接下来就是两个端的连接对象互相收发数据 。
TCP四次挥手的Socket过程:
一文读懂Socket通信原理

文章插图
  • 某个应用进程调用close()主动关闭 , 发送一个FIN;
  • 另一端接收到FIN后被动执行关闭 , 并发送ACK确认;
  • 之后被动执行关闭的应用进程调用close()关闭Socket , 并也发送一个FIN;
  • 接收到这个FIN的一端向另一端ACK确认 。
上面的代码是简单的演示Socket的基本函数使用 , 其实不管有多复杂的网络程序 , 这些基本函数都会用到 。上面的服务端代码只有处理完一个客户端请求才会去处理下一个客户端的请求 , 这样的服务器处理能力很弱 , 而实际中服务器都需要有并发处理能力 , 为了达到并发处理 , 服务器就需要fork一个新的进程或者线程去处理请求 。




推荐阅读