一、套接字发展史与分类

套接字起源于 20 世纪 70 年代加利福尼亚大学伯克利分校版本的 Unix,即人们所说的 BSD Unix。 因此,有时人们也把套接字称为“伯克利套接字”或“BSD 套接字”。一开始,套接字被设计用在同 一台主机上多个应用程序之间的通讯。这也被称进程间通讯,或 IPC。套接字有两种(或者称为有两个种族),分别是基于文件型的和基于网络型的。

基于文件类型的套接字家族

套接字家族的名字:AF_UNIX

unix一切皆文件,基于文件的套接字调用的就是底层的文件系统来取数据,两个套接字进程运行在同一机器,可以通过访问同一个文件系统间接完成通信

基于网络类型的套接字家族

套接字家族的名字:AF_INET

(还有AF_INET6被用于ipv6,还有一些其他的地址家族,不过,他们要么是只用于某个平台,要么就是已经被废弃,或者是很少被使用,或者是根本没有实现,所有地址家族中,AF_INET是使用最广泛的一个,python支持很多种地址家族)

总结:了解即可,但是由于我们只关心网络编程,所以大部分时候我么只使用AF_INET

二、套接字工作流程

一个生活中的场景。你要打电话给一个朋友,先拨号,朋友听到电话铃声后提起电话,这时你和你的朋友就建立起了连接,就可以讲话了。等交流结束,挂断电话结束此次交谈。 生活中的场景就解释了这工作原理。

先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束

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

三、基于tcp的套接字

tcp 客户端

import socket
# 实例化套接字对象
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 向客户端发起链接请求
phone.connect(('127.0.0.1',8080)) # 通信循环
while True:
msg = input("msg:::")
# 输入空格的话会把空传给缓存,但是缓存不会把这份数据传给服务端,服务端也就没法回信
# tcp中要避免输入空字符
if len(msg)==0:
continue
# 发送消息
phone.send(msg.encode('utf-8'))
# 指定接收消息的最大bytes
data = phone.recv(1024)
print(data.decode('utf-8'))
if msg =='q':
break
# 断开链接
phone.close()

tcp 服务端

import socket
# 实例化套接字对象
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)# sock_STREAM表示tcp为流式链接 # 绑定ip+port以便用户访问
phone.bind(('127.0.0.1',8080))
# 设置半连接池最大的状态
phone.listen(5)
# 监听循环
while True:
# 接收来自用户的链接请求,第一个参数是用户对象,第二个参数是用户地址
conn,client_addr = phone.accept() try:
while True:
# 设置最大接收数据量
data = conn.recv(1024)
# 在客户端发起断开链接时退出循环
if len(data) == 0:break
print('客户端send:',data.decode('utf-8'))
# 向客户端发送数据
conn.send(data.upper()) except Exception:
# 当客户端断开链接时,关闭通往客户端的通道
conn.close()

udp服务端

import socket

server=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) # 数据报协议=》udp协议
# 绑定一个端口
server.bind(('127.0.0.1',8081)) while True:
# udp没有建立链接的概念,只有直来直去的数据传输,分为数据部分和端口部分
data,client_addr=server.recvfrom(1024)
# 接收和传输都是要以数据,端口的元组形式进行传输
server.sendto(data.upper(),client_addr) server.close()

udp客户端

import socket

client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) # 流式协议=》tcp协议

while True:
msg=input('>>>: ').strip()
# udp中传输数据要跟上目标的ip+端口
client.sendto(msg.encode('utf-8'),('127.0.0.1',8081))
# 接受可以用解压赋值
res,addr=client.recvfrom(1024)
print(res.decode('utf-8')) client.close()

最新文章

  1. CSS3中border-radius、box-shadow与gradient那点事儿
  2. 拼sql条件时判断 是不是当前时间是不是周五,如果今天不是周五,就选上周五
  3. 如何快速从一个Storage Account拷贝到另一个账号
  4. C++ Primer : 第十三章 : 拷贝控制之对象移动
  5. 解决Maven项目编译时提示:源值1.5已过时,将在未来所有版本中删除
  6. 【开学季】自学嵌入式开发|四核开发板|4412开发板|ARM+Android+linux技术
  7. 错误与修复:ASP.NET无法检测IE10,导致_doPostBack未定义JavaScript错误,恒处于FF5卷动条位置
  8. (转)jquery ajax使用及跨域访问解决办法
  9. 多边形背景生成工具推荐-Trianglify
  10. B和B+树学习笔记
  11. 用Scertify Professional实现代码审查
  12. SharePoint场管理-PowerShell(二)
  13. 绩效考核指标KPI 听课笔记
  14. JAVA课程设计 学生成绩管理
  15. 2017广东工业大学程序设竞赛C题爬楼梯
  16. redis备份与恢复
  17. wpf研究之道——datagrid控件数据绑定
  18. 云服务器ECS优惠券 阿里云 ecs 5折优惠码 阿里云5折优惠码 阿里云5折推荐码 阿里云优惠码 阿里云的5折优惠券 阿里云服务器购买优惠码 服务器购买优惠码
  19. MYSQL—— Insert的几种用法!
  20. JavaScript面试的完美指南(开发者视角)

热门文章

  1. Swift 界面跳转
  2. 痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU启动那些事(11.0)- FlexSPI NOR启动时间(RT1170)
  3. WEditor(元素定位工具)安装和定位界面元素
  4. Dubbo——服务调用过程
  5. Windows 程序设计(4) MFC-02 基本控件-下
  6. 循序渐进VUE+Element 前端应用开发(12)--- 整合ABP框架的前端登录处理
  7. 如何从OutLook正确取得定期会议的时间?(待解决)
  8. Jenkins中agent的使用
  9. 查找nginx安装目录并启动
  10. Flutter学习笔记(38)--自定义控件之组合控件