socket套接字
把协议应用到我们程序上,发送一些数据,这个时候就需要socket
socket | 是对tcp/ip 协议的一个封装 |
---|
| socket不是协议 | | socket是一套调用的借口规范(API) | | socket分为UDP编程,TCP编程,2种 |
传输层
应用层+表示层+会话层
socket调用TCP
socket调用UDP
TCP
UDP
应用层程序
IP协议`网络
链路层
应用层=(应用层+表示层+会话层)
python中的网络编程
python网络编程的有2种网络服务,高级,低级
网络服务级别 | 内容 |
---|
低级 | 支持基本的socket 标准的BSD Sockets API 可以访问底层操作系统Socket接口的全部方法 | 高级 | SocketServer模块 服务器中心类 简化网络服务器的开发 |
python中还有其他应用级网络协议:FTP,HTTP的更高级别访问库 |
---|
Python Socket 模块库
Python Socket 模块库 | 基础的网络通信 |
---|
提供的属性和方法 | 1.创建Socket 2.地址绑定 3.TCP 或 UDP 协议的实现 4.接收,发送数据 5.关闭连接 |
创建过程 | TCP | UDP |
---|
1.创建Socket对象 | 创建套接字 socket.socket([family[,type[,proto]]]) -family:套接字家族可以使用 AF_UNIX 【 unix 系统之间进程通信】或 AF_INET 【tcp/ip 协议族使用这个参数表示IPv4】 AF_INET6【tcp/ip 协议族使用这个参数表示IPv6】 -type:套接字类型可以根据是面向连接还是非连接分为 SOCK_STREAM 【tcp面向字节流-使用】 SOCK_DGRAM 【udp数据报-使用】 创建实例: s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) | s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) | 2.1服务端地址绑定 | 绑定主机地址和端口号 绑地址和端口号 -s.bind((host,port)) | 绑定主机地址和端口号 绑地址和端口号 -s.bind((host,port)) | 2.2服务器端监听数量 | 开始TCP监听(转化为被动连接) 监听数量,不可为0 -s.listen(n) | 无连接 | 2.3服务器端等待连接 | 接受客户端连接,持续等待连接 -s.accept() 返回值有2个,需要用变量来装载 刚刚接受的客户端套接字,这个客户端的地址=s.accept() 当接收了一个之后,也就是调用完之后, 那么之间创建的socket就再去等待其他的客户端连接 | 无连接 | 3.客户端连接服务器 | 客户端主动初始化TCP服务连接 地址+端口:address=(host,port) s.connect(address) | 无连接 | 4.1客户端接收数据 | -s.recv(bufferfsize[,flags]) 从套接字接收TCP数据,返回字节对象, buffersize制定一次接收的最大数据量 buffer size也叫缓冲尺寸 | -s.recvfrom(bufsize[.flags]) 接受UDP数据,与recv()类似. 返回值为字节对象和地址(bytes,address) | 4.2 客户端/服务端 通用发送一次数据 | -s.send(bytes[,]flags) 发送数据给套接字 发送的是字节数据, 如本地的是utf8格式的数据需要转换为字节才可以发送 | 没有这个 | 4.3 客户端/服务端 通用发送数据 | 没有这个 | -s.sendto(bytes,address) 发送UDP数据到套接字 address形式为(ipaddr,port)的元组 返回值是发送的字节数 | 4.4 客户端/服务端 通用发送数据 | -s.sendall(bytes[,flags]) 持续从bytes发送数据 直到所有数据发送完毕或发生错误为止 (成功返回None,失败抛出异常) | 没有这个 | 4.5 客户端/服务端 发送文件 | -s.sendfile(file,offset=0,count=None) | | 5.关闭连接 | s.close() 四次挥手 | s.close() 直接关闭 |
通用方法 | |
---|
1.获取socket地址 | s.getpeername() 返回套接字的远程地址 返回值的形式一般是元组(ipaddr.port) s.getsockename() 返回套接字自己的地址 | 2.设置连接超市时间 | s.settimeout(timeout) 设置套接字操作的超市时间,单位是s,秒,浮点数值 | 3.获取主机名 | 获取主机名 -host=socket.gethostname() | 4.缓冲区大小 | 服务端接收数据的缓冲区。 当如果buffersize设置的比较小,那么获取到客户端发送过来的一部分数据。 想获取客户端发送过来的所有数据,则需要循环不断的调用recv()方法。 怎么判断后面还有其他未读的数据. 根据当前读取的字节数是否小于缓冲区的尺寸来判断是否后面还有其他未读的数据,如果没有,则终止循环 |
UDP通信流程
服务器端 | 创建socket | 绑定地址/端口 | 发送/接收数据 | 关闭 |
---|
客户端 | 创建socket | ---- | 发送/接收数据 | 关闭 |
TCP通信流程
服务器端 | 创建socket | 绑定地址/端口 | 转化为被动连接 | 接收客户端连接 | 接收/发送数据 | 关闭 |
---|
客户端 | 创建socket | – | – | 连接服务器 | 发送/接收数据 | 关闭 |
客户端与服务端的绑定端口
客户端 | 服务端 |
---|
从下面的图里面只有服务端socket需要绑定端口号,其实客户端socket在和服务端Socket连接时也需要一个端口号 客户端socket的端口号一般是自动产生和绑定的,这个端口由socket的对象accept()方法返回。每一个客户端socket的端口一般都是不同的 | 必须绑定 |
字节流<转换>utf-8
编码 | encode 把看的懂的编辑成机器传输的字节 格式为:变量=“python默认的utf-8字符格式” 变量.encode(“utf-8”) 编码成byte 把utf-8的字符串编辑成看不懂的字节-----用来给socket传输 得到"python\xe9\xbb\x98\xe8\xae\xa4\xe7\x9a\x84utf-8\xe5\xad\x97\xe7\xac\xa6\xe6\xa0\xbc\xe5\xbc\x8f“ |
---|
解码 | decode 把机器传输的字节解码成人能看懂的 格式为:变量=byte 变量=‘python\xe9\xbb\x98\xe8\xae\xa4\xe7\x9a\x84utf-8\xe5\xad\x97\xe7\xac\xa6\xe6\xa0\xbc\xe5\xbc\x8f’ 把byte解码成能看懂的UTF-8字符 变量.decode(‘utf-8’) 第二种写法:变量.decode(encoding=“utf-8”) 得到"python默认的utf-8字符格式" |
UDP通信图
TCP通信图
实例图,UDP通信
服务器端:udp1通信服务端接收信息.py 客户端:udp2通信客户端发送信息.py
先执行,udp1通信服务端接收信息.py
from socket import *
udp_socket=socket(AF_INET,SOCK_DGRAM)
udp_socket.bind(('127.0.0.1',8888))
recv_data,addr=udp_socket.recvfrom(1024)
print('收到ip为:%s,端口为:%s,发送过来的信息--%s--' % (addr[0],addr[1],recv_data.decode('utf-8')))
udp_socket.close()
后执行,udp2通信客户端发送信息.py
from socket import *
udp_socket=socket(AF_INET,SOCK_DGRAM)
address=('127.0.0.1',8888)
udp_socket.sendto("第1条信息".encode('utf-8'),address)
udp_socket.sendto("第2条信息".encode('utf-8'),address)
udp_socket.close()
实例图,TCP通信 服务器端:tcp1服务端.py 客户端:tcp2客户端.py
tcp1服务端.py
from socket import *
tcp_server_socket=socket(AF_INET,SOCK_STREAM)
address=('127.0.0.1',8888)
tcp_server_socket.bind(address)
tcp_server_socket.listen(999)
client_socket,clientAddr=tcp_server_socket.accept()
recv_data=client_socket.recv(1024)
print('接收到的数据为:',end="")
print(recv_data.decode('gbk'))
client_socket.send("问候文字,别发过来了!".encode('gbk'))
client_socket.close()
tcp2客户端.py
from socket import *
tcp_client_socket=socket(AF_INET,SOCK_STREAM)
server_ip='127.0.0.1'
server_port=8888
tcp_client_socket.connect((server_ip,server_port))
send_data=input('请输入要发送给的数据:')
tcp_client_socket.send(send_data.encode('gbk'))
recv_data=tcp_client_socket.recv(1024)
print('接收到的数据为:',end='')
print(recv_data.decode('gbk'))
tcp_client_socket.close()
|