专业理解: socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口,Socket其实就是使用一个门面模式(门面模式要求一个子系统的外部与其内部的通信必须通过一个统一的门面(Facade)对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用), 它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部.让socket去组织数据.
简易理解:socket就是一个模块,封装了网络通信所需要的所有东西.通过调用socket模块实现两个进程之间的连接和通讯.(也可称为:IP+Port , IP用于表示互联网中的一台主机的位置,而port则是定位到这个机器上的某个程序.)
套接字起源于 20 世纪 70 年代加利福尼亚大学伯克利分校版本的 Unix,即人们所说的 BSD Unix。 因此,有时人们也把套接字称为“伯克利套接字”或“BSD 套接字”。一开始,套接字被设计用在同 一台主机上多个应用程序之间的通讯。这也被称进程间通讯,或 IPC。套接字有两种(或者称为有两个种族),分别是基于文件型的和基于网络型的。
两个种族:
1.基于网络类型的套接字:AF_INET
(还有AF_INET6被用于ipv6,还有一些其他的地址家族,不过,他们要么是只用于某个平台,要么就是已经被废弃,或者是很少被使用,或者是根本没有实现,所有地址家族中,AF_INET是使用最广泛的一个,python支持很多种地址家族,但是由于我们只关心网络编程,所以大部分时候我么只使用AF_INET)
2.基于文件类型的套接字:AF_UNIX
unix一切皆文件,基于文件的套接字调用的就是底层的文件系统来取数据,两个套接字进程运行在同一机器,可以通过访问同一个文件系统间接完成通信
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是基于链接的,必须先启动服务端,然后再启动客户端去链接服务端
### Client 客户端 import socket client=socket.socket() # 创建 socket对象 client.connect(('127.0.0.1',8848)) # 连接服务端地址,端口号8848 # 发送数据 client.send('abcd'.encode('utf-8')) # 客户端 发送字节类型数据 from_server_data=client.recv(1024) # 客户端接收服务端响应的数据 print(from_server_data) client.close() # 关闭客户端连接 ### server服务端 import socket server=socket.socket() # 1 . 创建 socket的server对象 server.bind(('127.0.0.1',8848)) # 2 . 绑定IP 和端口 # 3. 监听 server.listen(5) # 4. 接受连接 conn,addr=server.accept() # 程序等待 print(conn,addr) # 打印 conn 连接信息 ,和addr地址信息 data=conn.recv(1024) # 接收客户端发送的数据 最多接收1024字节 conn.send(data.upper()) # 发送给客户端数据 conn.close() # 关闭连接 server.close() #关闭服务 什么是粘包:
客户端不能一次性接收完服务器返回的信息.这些没有接收完的信息会保存在一个缓冲区内. 等下次连接再来时,先把上一次没有收完的数据给接收了.
### server import socket import subprocess server =socket.socket() server.bind(('127.0.0.1',8877)) server.listen(5) while 1: conn , addr=server.accept() print(conn,addr) while 1: try: cmd=conn.recv(1024) # 接收客户端发来的cmd 字节指令 print(cmd) # 执行本机cmd命令 obj=subprocess.Popen(cmd.decode('utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # 拼接返回信息 msg_right=obj.stdout.read() msg_err=obj.stderr.read() result=(msg_right+msg_err).decode('gbk').encode('utf-8') print(result.decode('utf-8')) # 向客户端发送结果 conn.send(result) except ConnectionResetError: break conn.close() server.close() ### client import socket client=socket.socket() #连接服务器 client.connect(('127.0.0.1',8877)) while 1: user_input=input('请输入指令:>>>').strip() # 发送指令 以字节形式 client.send(user_input.encode('utf-8')) # 接收返回结果 try: ser_data=client.recv(1024) print(ser_data.decode('utf-8')) except UnicodeDecodeError as e: print(e) client.close()转载于:https://www.cnblogs.com/dengl/p/11196638.html
相关资源:Python 网络编程之TCP客户端/服务端功能示例【基于socket套接字】