写博客最怕写什么? 系统原理,框架内核...
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 import socket 4 sk = socket.socket() ## 创建一个sk对象/实例 5 sk.bind(("127.0.0.1",9999,)) ##ip+端口是一个元祖 6 ##后面最后排5个 7 sk.listen(5) 8 # 接收客户端的请求 ,这会阻塞,就是一直等待,程序会停在这里 9 # 一旦有请求过来,会接受 10 while True: 11 ## 基于conn连接发送消息 12 conn,address = sk.accept() 13 print(address,conn)
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 import socket 4 obj = socket.socket() 5 obj.connect(("127.0.0.1",9999,)) 6 obj.close()
上面的代码是最最最原始的socket通信代码,下面给出一个进一步的代码;
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 import socket ##导入socket模块 4 sk = socket.socket() ## 创建一个sk对象/实例,即实例化socket对象 5 sk.bind(("127.0.0.1",9999,)) ##ip+端口是一个元祖,定义好监听的IP地址和端口,可以绑定网卡上的IP地址,但是生产环境中一般绑定0.0.0.0这样所有网卡上都能够接收并处理这个端口的数据了 6 7 sk.listen(5) ##设定侦听开始并设定侦听队列里面等待的连接数最大为5 8 9 10 while True: # 接收客户端的请求 ,程序会阻塞在这里,就是一直等待,程序会停在这里;一旦有请求过来,会接受.好比老鸨在门口迎客(连接请求)... 11 print("服务器处于准备接受状态中...") 12 ## 可以基于conn 发信息 13 conn,address = sk.accept() ##conn拿到的是接入的客户端的对象,之后服务端和客户端通信都是基于这个conn对象进行通信,address获取的是连接的客户端的IP和端口. 14 ## conn好比一个小姐,从老鸨那里接手客人,老鸨腾空出来,迎接下一个连接请求... 15 conn.sendall(bytes("xx来电....", encoding='utf8')) 16 while True: #这个循环来实现相互之间通信的循环 17 try: ## 为什么要使用try包裹这一块呢?因为在通信过程中客户端突然退出了的话,服务端阻塞在recv状态时将会抛出异常并终止程序, 18 # 为了解决这个异常,需要我们自己捕获这个异常,这是在windows上,linux上不会抛出异常(测试依旧会...). 19 receiveBytes = conn.recv(1024) # 定义接收的数据大小为1024个字节并接受客户端传递过来的数据,注意这里的数据在python3中是bytes类型的, 20 # 在python3中网络通信发送和接收的数据必须是bytes类型的,否则会报错 21 receiveStr = str(receiveBytes,encoding='utf8') ##打印客户端传递过来的数据,需要从bytes类型数据解码成unicode类型的数据 22 if receiveStr == 'q': ##如果客户端传递过来的是q,就break当前循环,中断通信连接,跳到上层循环,继续等待下位客人 23 print("当前会话结束,感谢使用!") 24 break 25 conn.sendall(bytes(receiveStr+"好",encoding="utf8")) 26 except ConnectionResetError as e: ## 捕获到异常之后,打印异常出来并退出循环等待下一个客户端连接 27 print(e) 28 continue 29 ##返回接受到的信息 30 # print(str(receiveBytes)) 31 #py35中不能发字符串,而是发字节 32 # 33 print(address,conn)
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 import socket 4 obj = socket.socket() 5 obj.connect(("127.0.0.1",9999,)) 6 ## obj.recv 也是阻塞的 7 # print("waitint....") 8 receiveBytes = obj.recv(1024) ##超过1024,就下次在接收 9 # print("together...") 10 receiveStr = str(receiveBytes,encoding='utf8') 11 print(receiveStr) 12 while True: # 死循环实现通信 13 inp = input("请输入内容:") 14 if inp == 'q': 15 obj.sendall(bytes(inp, encoding='utf8')) 16 break 17 else: 18 obj.sendall(bytes(inp,encoding='utf8')) 19 receiveBytes = obj.recv(1024) 20 result = str(receiveBytes,encoding='utf8') 21 print(result) 22 obj.close()
上面给出的代码依旧是服务端和客户端一对一.即服务端在同一时间内,只能和一个客户端通信.这有毛病..
下面的代码,是使用python的socketserver模块,利用多线程,实现同一个服务端"同时"和多喝客户端通信.
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 import socketserver 4 class MyServer(socketserver.BaseRequestHandler): 5 def handle(self): 6 #print(self.request, self.client_address, self.server) 7 conn = self.request 8 conn.sendall(bytes("服务端正在处理你的请求...", encoding='utf8')) 9 while True: 10 recvB = conn.recv(1024) 11 resvS = str(recvB, encoding='utf8') 12 if resvS == "q": 13 print("当前会话结束,感谢使用!") 14 break 15 conn.sendall(bytes(resvS + "好", encoding='utf8')) 16 if __name__ == '__main__': 17 server = socketserver.ThreadingTCPServer(('127.0.0.1',9999,),MyServer) 18 server.serve_forever()
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 import socket 4 ck = socket.socket() 5 ck.connect(("127.0.0.1",9999,)) 6 recvB = ck.recv(1024) 7 print(str(recvB,encoding='utf8')) 8 while True: 9 inp = input("请输入聊天内容:") 10 if inp =="q": 11 ck.sendall(bytes(inp,encoding='utf8')) 12 break 13 else: 14 ck.sendall(bytes(inp, encoding='utf8')) 15 recvB1 = ck.recv(1024) 16 print(str(recvB1,encoding='utf8')) 17 ck.close()
socket模块博客到此结束....