Python学习记录4——在Ubuntu下使用Pycharm,被官方和谐了。
一.网截模块的简单应用
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 这就创建了一个服务端
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 设置端口复用,结束后能快速再打开
server.bind(('0.0.0.0', 12345)) # 绑定监听的ip和端口,ip可以修改为本地127.0.0.1
server.listen(120) # 最大接收客户端数量为120
while True: # 死循环监听
client, addr = server.accept()
recv_data = client.recv(1024).decode('utf-8') # 接收消息,最大字节数,编码
client.close() #收到消息 结束通讯
print(recv_data,addr)
server.close()
二.多线程接收(建议不使用)
这种虽然能接收多个客户端的消息,但是,它的发送只会发送给最新的客户端,而且一旦一个客户端断开连接,所有的客户端都会断开连接,如果不断连接,那么还有一个空线程在运行,总之,不建议使用。
import socket
import threading
address='127.0.0.1' #监听哪些网络 127.0.0.1是监听本机 0.0.0.0是监听整个网络
port=12345 #监听自己的哪个端口
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((address,port))
server.listen(2) #最大连接数
def tcplink(sock,addr):#单个线程获取数据
while True:
redata=clientsock.recv(2048).decode('utf-8')
if redata == "": #当用户退出时,会得到一个空消息
break
print(redata)
clientsock.close()
clientsock.close()
while True:
clientsock,clientaddress=server.accept()
t=threading.Thread(target=tcplink,args=(clientsock,clientaddress)) #创建的线程t
t.start() #启动线程
server.close()
三.真·多线程并发接收
因为经过我的测试,二中的代码并不能有效的进行接收,即使是多线程的,它也是个伪并发接收,我们需要修改模块,使用我们TCP通信的专属服务端模块 python自带的 socketserver模块
- 创建一个继承自"socketserver.BaseRequestHandler"的类,重写类方法handle.
- 当收到tcp连接时,会自动创建线程来运行handle,一旦handle运行完毕,这个线程就会被销毁,所以需要使用死循环来一直保持与客户端的连接,直到客户端主动退出,再break出循环。
- 使用ThreadingTCPServer函数,创建实例,并传递参数。
- 使用运行serve_forever(),运行实例,并永远运行除非发生异常。这模块也挺好的,用try把handle包起来的,也减小了意外发生。
代码:
import socketserver
class SockServer(socketserver.BaseRequestHandler):
def handle(self):
request = self.request
request.sendall("welcome to the tcp server\r\n".encode('utf-8'))
while True:
data = request.recv(1024).decode('utf-8')
if data == '': #当tcp服务端收到一个空消息的时候,相当于客户端主动退出
print(self.client_address)
print("断开与%s的连接"%(self.client_address, )) #注意这个, 因为client_address是一个二元组
break
else:
print("收到%s的消息:\r\n%s"%(self.client_address,data))
request.sendall('server got your message\r\n'.encode('utf-8'))
if __name__ == '__main__':
tcp_server = socketserver.ThreadingTCPServer(('0.0.0.0', 12345), SockServer)
print('启动服务器!')
tcp_server.serve_forever()
四.发送
发送没写,但是看socket的代码就很容易知道怎么写。或者搜索其他人的文章也行。