ji
基
ben
本
gai
概
nian
念
Socket的起源
PART/01
在组网领域的首次使用是在1970年2月12日发布的文献IETF RFC33中发现的,撰写者为Stephen Carr、Steve Crocker和Vint Cerf。根据美国计算机历史博物馆的记载,Croker写道:“命名空间的元素都可称为套接字接口。一个套接字接口构成一个连接的一端,而一个连接可完全由一对套接字接口规定。”计算机历史博物馆补充道:“这比BSD的套接字接口定义早了大约12年。”
Socket
PART/02
socket(套接字)的存在可以让相同或者不同的设备在两个不同的进程之间进行通信,更加确切来说,套接字是使用Unix标准文件描述器让不同的计算机进行交流的一种方式。在Unix中,每一个不同I/O操作都是通过读或者写一个文件描述其实现的,而文件描述器其实本质上就是一个整数,通过这个整数可以对应一个打开的文件,而这个文件可以是一个网络连接、一个文本文件,亦或是一个终端等。
在一个开发者眼里,socket更像是一个底层的文件描述器,因为在我们开发的过程中,不管是对socket的处理还是对文件或者pipe(管道)处理的时候,都会调用read()或者write()函数。
Socket通信的双方可以分为客户端和服务器端,客户端的基本流程如下:
1.创建socket
2.连接到服务器
3.发送数据到服务器
4.从服务器接受数据
5.关闭连接
服务器端的步骤稍微多一些,主要增加了与端口绑定(bind)和监听(listen)、接受阻塞(accept)等流程。
shi
使
yong
用
chang
场
jing
景
Unix套接字用于客户端 - 服务器应用程序框架。 服务器是一个根据客户端的请求而执行相应功能的进程。 大多数应用层协议(如FTP,SMTP和POP3)都是基于套接字在客户端和服务器之间建立连接,然后在进行数据交换。
常用的交互模型
PART/01
TCP
UDP
chang
常
yong
用
lei
类
型
socket常用的类型有4中,分别是Steam Socket、Datagram Sockets、Raw Sockets 和Sequenced Packet Sockets 。我们经常使用的类型是前两种,第三种相对较少,第四种使用得就更少了。以下是对这些socket的简单介绍。
Stream Socket
PART/01
该Socket类型提供有序的、可靠的、双向的和基于连接的字节流,使用带外数据传送机制,为Internet地址族使用TCP。 保证了数据交互的可靠性。可以确保数据可靠的发送到对方。但是Stream Socket所占的资源更多。 TCP传送的是一个无记录边界概念的字节流。可以总结为TCP中没有用户可见的"分组"概念,它只是传送了一个字节流,我们无法准确地预测在一个特定的读操作中会返回多少字节。最最简单的例子来说,你通过send函数send 3次的数据可能在另一端接受的时候 2次就读取完了。
Datagram Sockets
PART/02
该Socket类型支持无连接的、不可靠的和使用固定大小(通常很小)缓冲区的数据服务,为Internet地址族使用UDP。 因为是使用UDP来实现数据通讯,因此它不能保证数据能够到达目的地,但是由于它不需要专用的网络链接,所以它所需的资源相对少的多。相对于TCP而言, TCP 协议在传输数据的时候,如果数据发生错误,那么将重新传输该错误的部分。但是这样以来常常会浪费很多时间,在一些讲究实时性的通讯过程中,这样做有些不切实际。例如我们在观看网络视频的时候,少量的数据丢失并不会有很严重的影响,因此我们就会用到UDP 这样的协议。
Raw Sockets
PART/03
该Socket类型为用户提供了访问底层通信协议的能力,该类型不适于一般的用户,它主要是用于有想法开发新的协议或者对现有协议进行自定义操作的研发人员。
Python实现简单网络编程
Socket模块
PART/01
首先使用socket.socket()函数来创建套接字socket.socket(socketfamily,sockettype,protocol=0)
参数一:地址簇
socket.AF_INET IPv4(默认)socket.AF_INET6 IPv6 socket.AF_UNIX只能够用于单一的Unix系统进程间通信
参数二:类型
socket.SOCK_STREAM流式socket , for TCP(默认)socket.SOCK_DGRAM数据报式socket , for UDP
socket.SOCKRAW原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCKRAW可以;其次,SOCKRAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IPHDRINCL套接字选项由用户构造IP头。
socket.SOCKRDM是一种可靠的UDP形式,即保证交付数据报但不保证顺序。
SOCKRAM用来提供对原始协议的低级访问,在需要执行某些特殊操作时使用,如发送ICMP报文。SOCK_RAM通常仅限于高级用户或管理员运行的程序使用。
socket.SOCK_SEQPACKET可靠的连续数据包服务参数三protocol一般不填,默认为,特定的地址家族相关的协议,如果是,则系统就会根据地址格式和套接类别,自动选择一个合适的协议。
套接字对象的内建方法
PART/02
s=socket.socket()
服务器端套接字函数
s.bind(address)绑定地址元组(主机名,端口号)到套接字
s.listen(backlog))开始tcp监听
s.accept()被动接受tcp客户端连接,(阻塞式)等待连接的到来,返回客户端套接字对象和客户端地址
客户端套接字函数
s.connect(address)主动初始化TCP服务器连接
s.connect_ex( address)connect()函数的扩展版本,出错时返回出错码,而不是抛出异常
公共用途的套接字函数
s.recv(buffersize, flags=None)接受tcp数据
s.send(data, flags=None)发生tcp数据
s.sendall(data, flags=None)完整发生tcp数据
s.recvfrom( buffersize, flags=None)接受udp数据
s.sendto( data, flags=None, *args,kwargs)**发生udp数据
s.getpeername()连接到当前套接字的远端地址
s.getsockname()当前套接字的地址
s.getsockopt(level, option, buffersize=None)返回指定套接字的参数
s.setsockopt()设置指定套接字的参数
s.close()关闭套接字
s.ioctl(cmd, option)s.ioctl(socket.SIORCVALL, socket.RCVALLON)限定一个系统接口
面向模块的套接字函数
s.setblocking( flag)设置套接字的阻塞与非阻塞模式
s.settimeout()设置阻塞套接字操作的超时时间
s.gettimeout(timeout)得到阻塞套接字的超时时间
面向文件的套接字函数
s.fileno()套接字的文件描述符
s.makefile()创建一个与该套接字的关联的文件对象
创建TCP客户端与服务器通信
PART/03
client.py
import socket
con=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
con.connect(('192.168.88.132',8888))
while True:
try:
user=raw_input("\033>>>\033:")
con.sendall(user)
except Exception:
break
print str(con.recv(1024))
con.close()12345678910111213
server.py
#coding:utf-8
import socket
server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(('0.0.0.0',8888))
server.listen(5)
while True:
print "listenning...."
con,add=server.accept()
while True:
try:
print con.recv(1024)
message=raw_input("\033>>>\033:")
con.sendall(message)
except Exception:
break
con.close()
can
参
kao
考
Socket指南
https://www.tutorialspoint.com/unix_sockets/what_is_socket.htm
4.2BSD
http://digitalassets.lib.berkeley.edu/techreports/ucb/text/CSD-83-146.pdf
邮箱:ie-evolution@ie-evolution.xin
网站:
www.i-learner.xin
www.ie-evolution.xin
知乎专栏:IE进化论
公众平台:IE进化论(ie_evolution)
领取专属 10元无门槛券
私享最新 技术干货