网络编程案例多任务版tcp服务端程序开发(代码片段)

ZSYL ZSYL     2023-02-14     358

关键词:

案例-多任务版TCP服务端程序开发

学习目标

  • 能够说出多任务版TCP服务端程序的实现过程

1. 需求

目前我们开发的TCP服务端程序只能服务于一个客户端,如何开发一个多任务版的TCP服务端程序能够服务于多个客户端呢?

完成多任务,可以使用 线程,比进程更加节省内存资源。

2. 具体实现步骤

  1. 编写一个TCP服务端程序,循环等待接受客户端的连接请求
  2. 当客户端和服务端建立连接成功,创建子线程,使用子线程专门处理客户端的请求,防止主线程阻塞
  3. 把创建的子线程设置成为守护主线程,防止主线程无法退出。

3. 多任务版TCP服务端程序的示例代码

import socket
import threading


# 处理客户端请求的任务
def handle_client_request(ip_port, new_client):
    print("客户端的ip和端口号为:", ip_port)
    # 5. 接收客户端的数据
    # 收发消息都使用返回的这个新的套接字
    # 循环接收客户端的消息
    while True:
        recv_data = new_client.recv(1024)
        if recv_data:
            print("接收的数据长度是:", len(recv_data))
            # 对二进制数据进行解码变成字符串
            recv_content = recv_data.decode("gbk")
            print("接收客户端的数据为:", recv_content, ip_port)

            send_content = "问题正在处理中..."
            # 对字符串进行编码
            send_data = send_content.encode("gbk")
            # 6. 发送数据到客户端
            new_client.send(send_data)
        else:
            # 客户端关闭连接
            print("客户端下线了:", ip_port)
            break
    # 关闭服务与客户端套接字,表示和客户端终止通信
    new_client.close()


if __name__ == '__main__':

    # 1. 创建tcp服务端套接字
    # AF_INET: ipv4 , AF_INET6: ipv6
    tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置端口号复用,表示意思: 服务端程序退出端口号立即释放
    # 1. SOL_SOCKET: 表示当前套接字
    # 2. SO_REUSEADDR: 表示复用端口号的选项
    # 3. True: 确定复用
    tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    # 2. 绑定端口号
    # 第一个参数表示ip地址,一般不用指定,表示本机的任何一个ip即可
    # 第二个参数表示端口号
    tcp_server_socket.bind(("", 9090))
    # 3. 设置监听
    # 128: 表示最大等待建立连接的个数
    tcp_server_socket.listen(128)
    # 4. 等待接受客户端的连接请求
    # 注意点: 每次当客户端和服务端建立连接成功都会返回一个新的套接字
    # tcp_server_socket只负责等待接收客户端的连接请求,收发消息不使用该套接字
    # 循环等待接受客户端的连接请求
    while True:

        new_client, ip_port = tcp_server_socket.accept()
        # 代码执行到此,说明客户端和服务端建立连接成功
        # 当客户端和服务端建立连接成功,创建子线程,让子线程专门负责接收客户端的消息
        sub_thread = threading.Thread(target=handle_client_request, args=(ip_port, new_client))
        # 设置守护主线程,主线程退出子线程直接销毁
        sub_thread.setDaemon(True)
        # 启动子线程执行对应的任务
        sub_thread.start()

    # 7. 关闭服务端套接字, 表示服务端以后不再等待接受客户端的连接请求
    # tcp_server_socket.close()  # 因为服务端的程序需要一直运行,所以关闭服务端套接字的代码可以省略不写

执行结果:

客户端连接成功: ('172.16.47.209', 51528)
客户端连接成功: ('172.16.47.209', 51714)
hello1 ('172.16.47.209', 51528)
hello2 ('172.16.47.209', 51714)

4. 小结

  1. 编写一个TCP服务端程序,循环等待接受客户端的连接请求
while True:
	service_client_socket, ip_port = tcp_server_socket.accept()
  1. 当客户端和服务端建立连接成功,创建子线程,使用子线程专门处理客户端的请求,防止主线程阻塞
 while True:
     service_client_socket, ip_port = tcp_server_socket.accept() 
     sub_thread = threading.Thread(target=handle_client_request, args=(service_client_socket, ip_port))
     sub_thread.start()
  1. 把创建的子线程设置成为守护主线程,防止主线程无法退出。
 while True:
     service_client_socket, ip_port = tcp_server_socket.accept() 
     sub_thread = threading.Thread(target=handle_client_request, args=(service_client_socket, ip_port))
     sub_thread.setDaemon(True) 
     sub_thread.start()

模拟QQ聊天-客户端

from socket import *
from threading import Thread

flag = True

def readMsg(client_socket):
    while flag:
        recv_data = client_socket.recv(1024)
        print('收到:', recv_data.decode('utf-8'))


def writeMsg(client_socket):
    global flag

    while flag:
        msg = input('>')
        msg = user_name+'说:'+msg

        client_socket.send(msg.encode('utf-8'))
        if msg.endswith('bye'):
            flag = False
            break


# 创建客户端套接字对象
client_socket = socket(AF_INET, SOCK_STREAM)
user_name = input('请输入用户名:')
# 调用connect连接服务器
client_socket.connect(('192.168.0.108', 8888))

# 开启一个线程处理客户端的读取消息
t1 = Thread(target=readMsg, args=(client_socket,))
t1.start()

# 开启一个线程处理客户端的发送消息
t2 = Thread(target=writeMsg, args=(client_socket,))
t2.start()

t1.join()
t2.join()

client_socket.close()

模拟QQ聊天-服务端

from socket import *
from threading import Thread

# 存储所有的sockets
sockets = []

def main():
    # 创建server_socket套接字对象
    server_socket = socket(AF_INET, SOCK_STREAM)

    # 绑定端口
    server_socket.bind(('', 8888))

    # 监听
    server_socket.listen()

    # 接收客户端的请求
    server_socket.accept()

    while True:
        client_socket, client_info = server_socket.accept()
        sockets.append(client_socket)

        # 开启线程处理当前客户端的请求
        t = Thread(target=readMsg, args=(client_socket,))
        t.start()

def readMsg(client_socket):
    # 读取客户端发送来的消息
    while True:
        recv_data = client_socket.recv(1024)

        # 如果接收的消息中结尾是bye,则在客户端列表移除
        if recv_data.decode('utf-8').endswidth('bye'):
            sockets.remove(client_socket)
            client_socket.close()
            break
            

        # 将消息发送给所有在线的客户端
        # 遍历所有在线客户端列表
        if len(recv_data) > 0:
            for socket in sockets:
                socket.send(recv_data)


if __name__ == '__main__':
    main()

加油!

感谢!

努力!

python网络编程之多任务版tcp服务端程序开发

 一、需求目前我们开发的TCP服务端程序只能服务于一个客户端,如何开发一个多任务版的TCP服务端程序能够服务于多个客户端呢?完成多任务,可以使用线程,比进程更加节省内存资源。二、具体实现步骤编写一个TCP服务端... 查看详情

网络编程套接字(tcp)(代码片段)

目录1、实现一个TCP网络程序(单进程版)        1.1、服务端serverTcp.cc文件                 服务端创建套接字                 服务端绑定                 服务端监听               ... 查看详情

tcp案例代码(代码片段)

文章目录TCP网络编程的案例代码普通服务端/客户端代码多线程方式代码TCP网络编程的案例代码描述客户端与服务端的通信普通服务端/客户端代码服务端importjava.io.*;importjava.net.ServerSocket;importjava.net.Socket;/***服务端*/publicclassServerSo... 查看详情

java网络多线程专题(代码片段)

...;相关方法:代码展示:Socket:TCP网络通信编程应用案例(使用字节流)服务端代码客户端代码:TCP网络通信编程应用案例2服务端代码:客户端代码 查看详情

史上最全的python的web开发和网络编程附属详细解释+案例(代码片段)

文章目录1.IP地址2.端口2.1端口介绍2.2端口号介绍3.TCP3.1为什么要用TCP?3.2TCP和UDP的解释3.3TCP步骤和特点4.socket(套接字)5.TCP网络应用程序开发流程(重要)5.1刚安装ubuntu20遇到的问题5.2TCP两个程序开发过程5.3TCP客户端开发程序5.3TCP... 查看详情

linux网络编程基础及多线程并发案例(代码片段)

目录1.ip:端口 TCP/IP协议   2.socket头文件  sys/socket.h     3.字节序4.ip地址转换函数5.sockaddr和sockaddr_in6.服务器端基本函数bind listenaccept7.客户端基本函数  connect8.send和recv 8.多线程9.通信流程10.多线程并发样例程序 1.ip:端口 ... 查看详情

python搭建本地静态web服务器(多任务进阶版)(代码片段)

Python搭建本地静态Web服务器静态Web服务器-多任务版1.静态Web服务器的问题2.静态Web服务器-多任务版的示例代码3.小结静态Web服务器-面向对象开发1.以面向对象的方式开发静态Web服务器2.静态Web服务器-面向对象开发的示例代码3.小... 查看详情

网络编程tcp/ip协议-----多进程多线程服务器(代码片段)

1、前言上一篇已经实现了服务器端与客户端之间最基础通信,但存在一些问题,最大的问题是上篇中一个服务器端只能连接一个客户端,如何让一个服务器端可以连接多个客户端呢?利用多进程多线程实现。2、... 查看详情

静态web服务器-多任务版(代码片段)

学习目标能够写出多线程版的多任务web服务器程序1.静态Web服务器的问题目前的Web服务器,不能支持多用户同时访问,只能一个一个的处理客户端的请求,那么如何开发多任务版的web服务器同时处理多个客户端的请求?... 查看详情

java案例:基于tcp的简单聊天程序(代码片段)

文章目录一、如何实现TCP通信二、编写C/S架构聊天程序(一)编写服务器端程序-Server.java(二)编写客户端程序-Client.java(三)测试服务器端与客户端能否通信(四)程序优化思路-服务器端采用多... 查看详情

网络编程tcp网络应用程序开发(代码片段)

【网络编程】TCP网络应用程序开发TCP网络应用程序开发流程1.TCP网络应用程序开发流程的介绍2.TCP客户端程序开发流程的介绍3.TCP服务端程序开发流程的介绍4.小结TCP客户端程序开发1.开发TCP客户端程序开发步骤回顾2.socket类的介绍... 查看详情

linux网络编程套接字(中)(代码片段)

🎇Linux:博客主页:一起去看日落吗分享博主的在Linux中学习到的知识和遇到的问题博主的能力有限,出现错误希望大家不吝赐教分享给大家一句我很喜欢的话:看似不起波澜的日复一日,一定会在某一天... 查看详情

网络传输--tcp(代码片段)

TCP网络编程一、TCP简介二、TCP网络程序--客户端三、TCP网络程序--服务端四、TCP知识总结五、文件下载案例六、3次握手和4次挥手回到顶部 一、TCP简介TCP1.TCP的简介  TCP通信需要通过创建链接,数据传送,终止链接3个步骤  2... 查看详情

tcp编程(字节读写)-socket网络应用(代码片段)

...的应用程序属客户端,等待通信请求的为服务端应用案例(字节流):1.编写一个服务器端和一个客户端;2.服务端在9999端口监听;3.客户端连接服务端,发送“hello,server”,并接收服务端发回的“h... 查看详情

网络编程之tcp客户端开发和tcp服务端开发(代码片段)

开发TCP客户端程序开发步骤创建客户端套接字对象和服务端套接字建立连接发送数据接收数据关闭客户端套接字 importsocketif__name__==‘__main__‘:#创建tcp客户端套接字#1.AF_INET:表示ipv4#2.SOCK_STREAM:tcp传输协议tcp_client_socket=socket.so... 查看详情

linux网络(c++)——网络套接字(tcp/udp编程模型)多进程,多线程,线程池服务器开发(画图解析)(代码片段)

目录一.套接字基本概念📚  IP地址📚 TCP和UDP协议 📚 端口号 📚 端口号vs进程pid📚 网络字节序本地字节序转换成网络字节序网络字节序转换为本地字节序二.套接字的基本操作📚 socket的创建域(domai... 查看详情

12.7网络编程案例(代码片段)

12.7网络编程案例 12.7.1TCP多线程时间服务器主要功能: 子类化方式继承QTcpServer与QThread,创建TCP服务器,等待客户端连接,连上新的客户端之后,服务器获取本地时间,将时间发送给客户端,再断开连接,销毁线程。(配套... 查看详情

socket多线程编程(代码片段)

前面一片学习了TCP/IP的基础网络编程,并给出了简单的服务端与客户端通信交互的例子。还介绍了UPC的通信例子。这次学习TCP/IP的多线程编程。因为涉及到TCP/IP一般都是多线程,服务端会一直监听端口,多个客户端发来信息,收... 查看详情