博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python学习之——Socket套接字(TCP连接)
阅读量:4508 次
发布时间:2019-06-08

本文共 3385 字,大约阅读时间需要 11 分钟。

套接字基础

C/S架构,即客户端/服务器架构,B/S架构(浏览器/服务器),也属于C/S架构

socket介绍

socket套接字就是为了完成C/S架构软件的开发。socket依赖于网络,所以骚年,网络基础不能忘了。

在Python中,socket子层位于TCP/IP协议栈的传输层和应用层的中间层,是一个提供向上向下接口的软件抽象层。socket封装了tcp和udp协议,所以遵循socket语法写出的程序遵循tcp和udp协议

注:socket = IP + port,ip用来标识网络中主机的位置,port用来标识主机的应用,所以ip + port能够标识互联网中的唯一一个应用,所以说socket其实就是IP和端口的组合

socket分类

网络编程只需要关注AF_INET,这种是应用最广泛的,如果是用于ipv6平台需要用AF_INET6。

其他:AF_UNIX,用于UNIX文件系统间通信、还有很多其他的平台使用的。

socket通信原理

上图为sockettcp通信过程

1.服务器先初始化socket,然后与端口绑定(bind),对端口进行监听(listen)并调用accept阻塞等待

2.客户端连接先初始化一个socket,然后连接服务器(connect),如果正常访问到了服务器端,服务器端阻塞结束,连接成功,这时客户端与服务器端的连接建立。

3.客户端发送数据请求,服务器端接收请求并处理请求,然后服务器把回应数据发送给客户端,客户端读取数据,循环。

4.最后客户端或者服务端关闭连接,一次交互结束。

 

socket模块

如:基于本地环回地址的一次性套接字通信

服务端:

#导入socket模块import socket#创建socket,类似于买手机skt=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#绑定端口和ip,必须为元组类型,类似于手机插卡#,如果元组为('',9000)表示本机所有的网卡,相当于0.0.0.0skt.bind(('127.0.0.1',9000))#侦听访问端口,类似于手机待机#若括号中有值,则表示对TCP连接的优化skt.listen()#此处循环表示服务器持续提供服务while True:    #conn表示接受的数据流,addr表示客户端的地址    conn,addr=skt.accept()    #接受客户端发送消息并打印    msg=conn.recv(1024)    print(msg.decode('utf-8'))    print(msg,type(msg))    #为客户端返回消息,表示接受成功    conn.send(msg.upper())    #关闭本次通信    conn.close()    #关闭链接    skt.close()

客户端

#导入socket模块import  socket#创建socketskt = socket.socket(socket.AF_INET,socket.SOCK_STREAM)#与服务端建立链接skt.connect(('127.0.0.1',9000))#发送消息msg = b'Hello'skt.send(msg)#接受服务端返回值并打印res = skt.recv(100)print(res.decode('utf-8'))#关闭会话链接skt.close()

#相关值说明

1 socket.socket(socket_family,socket_type,protocal=0)2 socket_family可以是 AF_UNIX 或 AF_INET3 socket_type 可以是 SOCK_STREAM(面向连接的可靠数据传输,即TCP协议)或 SOCK_DGRAM(面向无连接的不可靠数据传输,即UDP)4 protocol 一般不填,默认值为 0

#相关方法说明

1 服务端套接字函数 2 s.bind()    绑定(主机,端口号)到套接字 3 s.listen()  开始TCP监听 4 s.accept()  被动接受TCP客户的连接,(阻塞式)等待连接的到来 5  6 客户端套接字函数 7 s.connect()     主动初始化TCP服务器连接 8 s.connect_ex()  connect()函数的扩展版本,出错时返回出错码,而不是抛出异常 9 10 公共用途的套接字函数11 s.recv()            接收TCP数据12 s.send()            发送TCP数据(send在待发送数据量大于己端缓存区剩余空间时,数据丢失,不会发完)13 s.sendall()         发送完整的TCP数据(本质就是循环调用send,sendall在待发送数据量大于己端缓存区剩余空间时,数据不丢失,循环调用send直到发完)14 s.recvfrom()        接收UDP数据15 s.sendto()          发送UDP数据16 s.getpeername()     连接到当前套接字的远端的地址17 s.getsockname()     当前套接字的地址18 s.getsockopt()      返回指定套接字的参数19 s.setsockopt()      设置指定套接字的参数20 s.close()           关闭套接字21 22 面向锁的套接字方法23 s.setblocking()     设置套接字的阻塞与非阻塞模式24 s.settimeout()      设置阻塞套接字操作的超时时间25 s.gettimeout()      得到阻塞套接字操作的超时时间26 27 面向文件的套接字的函数28 s.fileno()          套接字的文件描述符29 s.makefile()        创建一个与该套接字相关的文件

 

#常见错误处理

 

 由于服务端仍然存在四次挥手的time_wait状态在占用地址(如果不懂,请深入研究1.tcp三次握手,四次挥手 2.syn洪水攻击 3.服务器高并发情况下会有大量的time_wait状态的优化方法)

最直接的解决方法,更改端口号

更多解决方法:

window解决方法

1 #加入一条socket配置,重用ip和端口2 phone=socket(AF_INET,SOCK_STREAM)3 phone.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #就是它,在bind前加4 phone.bind(('127.0.0.1',9000))

Linux解决方法

1 发现系统存在大量TIME_WAIT状态的连接,通过调整linux内核参数解决, 2 vi /etc/sysctl.conf 3  4 编辑文件,加入以下内容: 5 net.ipv4.tcp_syncookies = 1 6 net.ipv4.tcp_tw_reuse = 1 7 net.ipv4.tcp_tw_recycle = 1 8 net.ipv4.tcp_fin_timeout = 30 9  10 然后执行 /sbin/sysctl -p 让参数生效。11  12 net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;13 14 net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;15 16 net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。17 18 net.ipv4.tcp_fin_timeout 修改系統默认的 TIMEOUT 时间

 

转载于:https://www.cnblogs.com/yuxiang-qiwa/p/7965945.html

你可能感兴趣的文章
Selenium 上传文件失败,解决办法一
查看>>
2019年,我们需要加强关注网络安全的6大原因
查看>>
Hexo主题 —— NexT优化
查看>>
Python Web Flask源码解读(三)——模板渲染过程
查看>>
JavaScript 中的对象(一)- 对象的概念、模型、以及创建
查看>>
产品的痛点、爽点和痒点
查看>>
密码学摘要算法之SHA2
查看>>
dealloc和weak底层实现
查看>>
【网络】Windows 下 socket 编程范例
查看>>
【IT】CRC校验码是怎么回事呢?
查看>>
hashmap C++实现
查看>>
C++深拷贝和浅拷贝细节理解
查看>>
云风协程库coroutine源码分析
查看>>
【漫谈数据仓库】 如何优雅地设计数据分层 ODS DW DM层级
查看>>
POJ - 2559 && POJ - 3494 (单调栈)
查看>>
POJ - 2796 Feel Good (单调栈)
查看>>
2019牛客暑期多校训练营(第一场合集)
查看>>
2019牛客暑期多校训练营(第二场合集)
查看>>
2019牛客暑期多校训练营(第四场合集)
查看>>
树的直径
查看>>