socker编程技术
socket--一对一
- TCP协议与UDP协议
- TCP(transmission control protocol)可靠的,面向连接的协议(eg:打电话)、传输效率低,全双工通信(发送缓存&接收缓存)、面向字节流。使用TCP的应用:web浏览器、电子邮件、文件传输等
- UDP(user datagram protocol)不可靠的,无连接的服务,传输效率高(发送前时延小),一对一、一对多、多对一、多对多、面向报文,尽最大努力服务,无拥塞控制。使用UDP的应用:域名系统(DNS);视频流;IP语音(volp)--反正数据给你了,不管你拿不拿到
-
websocket基于应用层协议---HTTP
-
socket基于传输层协议---TCP
-
socket工作原理
-
1、服务器根据地址类型、socket类型、协议创建socket
-
2、服务器为socket绑定ip地址和端口号
-
3、服务器socket监听端口号请求,随时准备接收客户端发来的连接,这时候服务器的socket并没有打开
-
4、客户端创建socket
-
5、客户端打开socket,根据服务器IP地址和端口号试图连接服务器socket
-
6、服务器socket接收到客户端socket请求,被动打开,开始接收客户端请求,知道客户端返回连接信息。这时候socket进入阻塞状态,所谓阻塞即accept()方法一直等到客户端返回连接信息后返回,开始接收下一个客户端的连接请求
-
7、客户端连接成功,向服务器发送连接状态的信息
-
8、服务器accept方法返回,连接成功
-
9、客户端向socket写入信息(或服务端向socket写入信息)
-
10、服务器读取信息(客户端读取信息)
-
11、客户端关闭
-
12、服务端关闭
-
socket的常用方法
-
低级别的网络服务支持基本的socket,它提供了标准的SBD socket API,可以访问底层操作系统socket接口的全部方法
-
高级别的网络服务模块socketserver,他提供了服务器中心类,可以简化网络服务器的开发
-
什么是socket编程
- socket又称套接字,应用程序通常通过套接字向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯
socket函数
python中,我们用socket()函数来创建套接字,语法格式如下
socket.socket([family[,type[,proto]]]) 参数 * family:套接字家族可以使用AF_UNI或者AF_INET. * type:套接字类型可以根据是面向连接还是非连接分为SOCK_STREAM或SOCK_DGRAM. * protocol:一般不填默认为0
- socket又称套接字,应用程序通常通过套接字向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯
-
socket服务端
- 使用socket模块的socket函数来创建一个socket对象,socket对象可以通过调用其他函数来设置一个socket服务
- 可以通过调用bind(hostname,port)函数来指定服务的port(端口)
- 调用socket对象的accept方法,该方法等待客户端的连接,并返回connection对象,表示客户端已经连接到服务端
-
socket客户端
- socket。connect(hostname,port)方法打开一个TCP,连接到主机为hostname,端口为port的服务端
- 连接后就可以从服务端获取数据,记住,操作完成后需要关闭连接
socket代码
服务端代码:
import socket
ip_port=('127.0.0.1',8888)
#1-创建socket对象
sk=socket.socket()
#2-绑定ip port
sk.bind(ip_port)
#3-启动监听
sk.listen()
print('---服务器上线了---')
# 4-阻塞等待连接 返回 套接字 和 客户端的IP
conn,addr =sk.accept()
print('客户端的地址>>>:',addr)
#5-接收数据
client_data =conn.recv(1024).decode('utf-8')
print('接收到客户端的数据>>>',client_data)
#6-发送数据
send_data = input('请输入>>>')
conn.sendall(send_data.encode('utf-8'))
print('发送给客户端的数据>>>',send_data)
#7-关闭socket
conn.close()
客户端代码
import socket
ip_port=('127.0.0.1',8888)
#1-创建socket对象
sk=socket.socket()
#2-建立连接
sk.connect(ip_port)
#3-发送数据
send_data =input('请输入>>>')
sk.sendall(send_data.encode('utf-8'))
print('发送给服务端的数据>>>',send_data)
#4-接收数据
server_data =sk.recv(1024).decode('utf-8')
print('接收到服务端的数据>>>',server_data)
#5-关闭socket
sk.close()
局限:只能一对一聊天,不能多对多聊天
socketserver--一对多
socketserver代码
服务端:
import socketserver
#1-需要继承一个类BaseRequestHandler 实现handle方法
print('---服务启动完成,等待客户端中---')
class SKserver(socketserver.BaseRequestHandler):
def handle(self):
print('---有客户端上线了---')
#处理逻辑,self.request方法
while True:
#接收数据
client_data =self.request.recv(1024).decode('utf-8')
print('接收到客户端的数据>>>',client_data)
#发送数据
send_data=input('请输入:>>>')
self.request.sendall(send_data.encode('utf-8'))
print('发送给客户端的数据>>>',send_data)
self.request.close()
#2-创建服务,多线程方式ThreadingTCPServer
sk=socketserver.ThreadingTCPServer(('127.0.0.1',8888),SKserver)
#3-保持一直在线
sk.serve_forever()
客户A 客户B复制A的代码
import socket
ip_port=('127.0.0.1',8888)
#1-创建socket对象
sk=socket.socket()
#2-建立连接
sk.connect(ip_port)
while True:
#3-发送数据
send_data =input('a:'+'请输入>>>')
sk.sendall(send_data.encode('utf-8'))
print('发送给服务端的数据>>>',send_data)
#4-接收数据
server_data =sk.recv(1024).decode('utf-8')
print('接收到服务端的数据>>>',server_data)
#5-关闭socket
sk.close()
运行结果
客户端A:
a:请输入>>>a
发送给服务端的数据>>> a
接收到服务端的数据>>> aa
a:请输入>>>aaa
发送给服务端的数据>>> aaa
接收到服务端的数据>>> aaaa
a:请输入>>>
客户端B:
b:请输入>>>b
发送给服务端的数据>>> b
接收到服务端的数据>>> bb
b:请输入>>>bbb
发送给服务端的数据>>> bbb
接收到服务端的数据>>> bbbb
b:请输入>>>
问题记录
-
1、TypeError: recv() takes at least 1 argument (0 given)
client_data =conn.recv() TypeError: recv() takes at least 1 argument (0 given)
- 原因分析:
- 未指定接收数据大小
- 解决方法
- 指定数据大小
- client_data =conn.recv(1024)
- 原因分析:
-
2、TypeError: a bytes-like object is required, not 'str'
sk.sendall(send_data) TypeError: a bytes-like object is required, not 'str'
- 原因分析:
- 未指定编码格式,需要字节流而不是字符串
- 解决方法
- 指定编码格式为utf-8
- sk.sendall(send_data.encode('utf-8'))
- 原因分析:
-
3、OSError: [WinError 10048] 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。
self.socket.bind(self.server_address) OSError: [WinError 10048] 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。
- 原因分析:
- 当我们在PyCharm中把运行窗口中运行状态终结了,实质是执行的python程序还没有结束, 所以打开windows任务管理器,把名为python的进程统统结束。
- 解决方法
- 任务管理器,关闭python运行程序
- 任务管理器,关闭python运行程序
- 原因分析: