Python学习:Socket编程——多客户端通信聊天室
Posted sheeks
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python学习:Socket编程——多客户端通信聊天室相关的知识,希望对你有一定的参考价值。
最近学习Python,又需要学习一下网络编程的一些知识,写了一个简单的聊天室的程序。程序分为两个python文件,一个是server.py,另一个是client.py。
Socket编程的流程如下图所示:
服务端:
1.服务端需要创建一个socket对象。(socket())
2.为这个socket对象绑定ip地址和端口号。(bind())
3.让socket对象进入监听状态,传入的参数是指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。(listen())
4.在while True循环里接收客户端发送过来的连接请求,如果没有连接请求该循环会被阻塞。(accept()是否返回了值)
5.服务端接收到客户端发送过来的连接请求后(accept()有了返回值),返回一个新的socket对象和list类型的地址,这个list第0项是记录的ip,第1项是记录的端口号。
6.之后客户端会通过send(),sendall()等方法发送具体的数据给服务端,后续服务端与客户端会通过accept()返回的新socket对象来通信。这个新的socket对象要放在一个之前的while True循环下的一个新的while True循环来使用recv()获取消息。(recv(),send(),sendall())
客户端:
1.客户端创建一个socket对象。(socket())
2.客户端发起一个连接请求。(connect()) ====>对应服务端的4.
3.客户端发送数据。(send(),sendall()) ====>对应服务端的6.
通信的过程如上所述,但是还需要注意一些细节。socket通信通过byte来传递,字符串需要通过encode()编码成byte型才能传输。接收端需要将byte通过decode()解码才能转换为字符串。如果要传输对象,则需要导入pickle模块,通过pickle.dumps(object)来转化为可以传输的类型,通过pickle.loads(object)来还原回对象。
为了实现多客户端连接的功能,需要引入多线程。每当一个客户端发起连接时,就创建一个新的线程,这个线程就负责为这个客户端进行通信。这样就可以支持多线程的通信。userList是一个list,每当有客户端连接到服务端,就会将这一对连接的socket添加到list当中。这样之后该线程中接收到该客户端发送的信息后,会遍历这个list的每个元素,实现向每一个客户端转发该客户端发送的消息。
1 while True: 2 conn, addr = socket_server.accept() 3 # conn为新的socket对象,与服务器连接后的后续操作由conn去处理 4 userDict[conn] = addr 5 userList.append(conn) 6 thread = threading.Thread(target=newClientConnection, args=(conn, addr)) 7 thread.start()
1 while True: 2 words_byte = conn.recv(1024) 3 words = words_byte.decode() 4 print(words) 5 for c in userList: 6 c.sendall(words.encode())
为了实现客户端可以接收其他客户端发送的消息,同时又可以多次发送新的消息,需要创建两个线程,一个是接收消息的线程,一个是发送消息的线程。
1 thread_send = threading.Thread(target=sendMessage, args=(socket_client, name)) 2 thread_send.start() 3 thread_receive = threading.Thread(target=receiveMessage, args=(socket_client,)) 4 thread_receive.start()
def sendMessage(socket_client, name): while True: words = input() message = name + " : " + words socket_client.sendall(message.encode())
def receiveMessage(socket_client): while True: dataFromServer_byte = socket_client.recv(1024) str = dataFromServer_byte.decode() print(str)
需要注意threading模块创建线程时,"target="需要填入函数名,"args="需要填入该函数的参数,并且是以元组的形式填入,如果只有一个参数,需要在该参数后加一个”,“。
项目中Git知识的总结:
获取历史提交代码的版本
git log #查看历史提交记录和版本号
git branch 新分支名 版本号 #创建新分支,并且该新分支即为版本号对应版本的代码
git checkout 新分支名#切换到该新分支
合并本地版本其他分支到master分支
git checkout master
git merge 分支名
以上是关于Python学习:Socket编程——多客户端通信聊天室的主要内容,如果未能解决你的问题,请参考以下文章