先看一个实例,上代码:

#!/usr/bin/env python3
# _*_ coding:utf- _*_
import socket
sk = socket.socket()
sk.bind(("0.0.0.0",)) # 把IP绑定到套接字
sk.listen() # 监听链接 print("等待客户端连接....")
conn,addr = sk.accept() # 接收客户端链接
print("IP: %s Port: %s 已建立连接..." %(addr[],addr[])) client_data = conn.recv() # 接收客户端信息
print(client_data) #打印客户端信息息 conn.send(b"haha") # 向客户端发送信息 conn.close() # 关闭这次的连接
sk.close() # 关闭服务器socket,相当于停止了服务

基于tcp协议的socket server

运行以上代码: 使用 telnet 连接服务端

# 客户端退出连接, 再次启动服务端会报错,说端口已经被占用。

# 查看tcp状态,TIME_WAIT。。什么鬼  程序已经结束了,socket为啥还存在呢? 这是因为tcp协议的可靠性。

解决办法:

#加入一条socket配置,重用ip和端口

phone=socket(AF_INET,SOCK_STREAM)
phone.setsockopt(SOL_SOCKET,SO_REUSEADDR,) #就是它,在bind前加
phone.bind(('127.0.0.1',))

方法一:在代码中加参数

vi /etc/sysctl.conf

编辑文件,加入以下内容:
net.ipv4.tcp_syncookies =
net.ipv4.tcp_tw_reuse =
net.ipv4.tcp_tw_recycle =
net.ipv4.tcp_fin_timeout = 然后执行 /sbin/sysctl -p 让参数生效。 net.ipv4.tcp_syncookies = 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭; net.ipv4.tcp_tw_reuse = 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭; net.ipv4.tcp_tw_recycle = 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。 net.ipv4.tcp_fin_timeout 修改系統默认的 TIMEOUT 时间

linux系统: 设置内核参数

tcp协议三次握手与四次挥手

三次握手:

  

.客户端:
客户端发送syn信息给服务端,然后客户端从closed状态变为syn_send(请求建立连接)状态(三次握手的第一次握手)
.服务端:
①服务端从closed(关闭状态)状态转换为listen(监听状态)状态(在服务端开启相应服务),只有在listen状态才可以接收客户端建立连接请求
closed--listen状态,实际上就是创建了一个socket条目信息
②服务端在listen状态接收到客户端发送的syn请求,会响应syn和ack信息,并且从listen状态变为syn_rcvd状态(三次握手的第二次握手)
.客户端:
客户端在syn_send状态接收到syn和ack字段信息,然后回复ack确认信息(三次握手的第三次握手)
syn_send状态变为最终建立连接的状态(established)
.服务端:
服务端在syn_rcvd状态接收到了ack字段信息,从syn_rcvd状态变为established

tcp三次握手状态集的转换

四次挥手:

  

.客户端:
在established状态发送fin字段信息给服务端(四次挥手过程第一次挥手)
然后客户端状态转变为fin_wait1(第一次等待:服务端的确认ack信息)
.服务端:
① 服务端在established状态接收到客户端发送的fin字段信息,从established状态变为close_wait
② 服务端在close_wait发送ack确认字段(四次挥手的第二挥手)
.客户端
①客户端在fin_wait1状态接收服务端的ack信息,进入到fin_wait2(第二次等待:)
.服务端:
服务端在close_wait发送fin断开连接字段给客户端(四次挥手的第三次挥手)
服务端从close_wait变为last_ack状态
.客户端
客户端在fin_wait2状态接收服务端的fin信息,然后响应ack信息,并将自己的状态转变为time_wait状态
(四次挥手的第四次挥手)
.服务端:
服务端在last_ack状态接收到客户端发送的ack字段信息之后,就会最终变为closed状态
.客户端:
在time_wait会等待120秒钟时间,才能进入到closed状态

tcp四次挥手状态集的转换

tcp十一种状态集转换

最新文章

  1. SQL优化技术分析-2:SQL书写的影响
  2. Retina时代的前端视觉优化
  3. Linq使用Distinct删除重复数据时如何指定所要依据的成员属性zz
  4. AutoCompleteTextView的应用
  5. iOS绘图教程 (转,拷贝以记录)
  6. 函数响应式编程及ReactiveObjC学习笔记 (三)
  7. Java——静态变量/方法与实例变量/方法的区别
  8. 【UML】NO.47.EBook.5.UML.1.007-【UML 大战需求分析】- 部署图(Deployment Diagram)
  9. Head First Android --- Intent
  10. Expanded encryption and decryption signature algorithm SM2 & SM3
  11. 【LOJ】#2585. 「APIO2018」新家
  12. Python学习笔记009—函数
  13. MySQL使用全文索引(fulltext index)---高性能
  14. loj#6235. 区间素数个数(min25筛)
  15. Python的模块调用
  16. 怎样改动android系统字体大小
  17. [BZOJ2599]Race
  18. Redis 七月小说网的爬虫缓存设计
  19. 爬虫入门之Scrapy框架基础框架结构及腾讯爬取(十)
  20. mysql-debug: Thread stack overrun

热门文章

  1. python3获取天气预报
  2. [Songqw.Net 基础]WPF实现简单的插件化开发
  3. HDU-3839-Ancient Messages(DFS)
  4. Ubuntu更改 resolv.conf 重启失效
  5. wpf怎么使用WindowsFormsHost(即winform控件)
  6. Kinect 开发驱动配置
  7. win10 uwp 如何打包Nuget给其他人
  8. PHP 的魔术方法及其应用
  9. MySQL学习-SQL约束
  10. SSL Converter & Formats