1.工具开发socket编程技术
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运行程序
 ![图 3]() 
 
- 任务管理器,关闭python运行程序
 
- 原因分析:
 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号