python基础____学习笔记11( 网络编程,基于socket客户端和服务端)

一、网络编程
1.1    TCP 客户端程序开发流程

  • 创建客户端套接字对象
  • 和服务端套接字建立连接
  • 发送数据
  • 接收数据
  • 关闭客户端套接字

1.2 TCP 服务端程序开发流程
步骤说明:

  •     创建服务端端套接字对象
  •     绑定端口号
  •     设置监听
  •     等待接受客户端的连接请求
  •     接收数据
  •     发送数据
  •     关闭套接字

1.3 TCP 客户端程序开发
客户端尝试连接服务端, 不停向服务端发送数据,并且使用select 非阻塞IO监听是否有数据,当接收到数据为空则表示服务器已经下线,则重新尝试连接

import socket
import time
import select


SERVER_IP = "192.168.2.243"
SERVER_PORT = 8090
sendtime =0
isConnected = False

if __name__ == '__main__':
    # 创建tcp客户端套接字
    # 1. AF_INET:表示ipv4
    # 2. SOCK_STREAM: tcp传输协议
    while True:
        if isConnected == False:
            try:
                print("try to connect server !")
                tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                tcp_client_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
                tcp_client_socket.connect((SERVER_IP, SERVER_PORT))
            except:
                isConnected = False
                time.sleep(1)
                continue
            else:
                isConnected = True
                print("connect %s ok!" %(SERVER_IP,))

        sendtime += 1
        send_data = f"Hello world-- {sendtime} times!".encode("gbk")
        tcp_client_socket.send(send_data)
        inputs =[tcp_client_socket]
        rs, ws, es = select.select(inputs, [], [],0.3)
        for r in rs:
            if r is tcp_client_socket:
                try:
                    msg=tcp_client_socket.recv(2048)
                except socket.error as error:
                    print("server disconnect!")
                    tcp_client_socket.close()
                    isConnected = False     # 断开了连接
                    break
                else:   #接收成功
                    if not msg:
                        isConnected = False  # 断开了连接
                        tcp_client_socket.close()
                        print("server disconnect!")
                        break
                    else:
                        print(f'Recv msg {msg} from server {SERVER_IP}')





1.4 多连接服务器开发-子线程实现
子线程设置为守护线程,避免主线程无法退出
建立子线程接收数据,避免 主线程调用recv函数阻塞

acept 返回2个值 : 客户端socket 和地址

import socket
import threading

# 处理客户端的请求操作
def handle_client_request(service_client_socket, ip_port):
    # 循环接收客户端发送的数据
    while True:
        #阻塞接受客户端数据
        recv_data = service_client_socket.recv(1024)
        #通过容器判断是否接收为空,为空 表示客户端已经断开连接。
        if recv_data:
            print(recv_data.decode("gbk"), ip_port)
            # 回复
            service_client_socket.send("ok,问题已经收到...".encode("gbk"))
        else:
            print("客户端下线了:", ip_port)
            break
    # 终止和客户端进行通信
    service_client_socket.close()

if __name__ == '__main__':
    tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置端口号复用,让程序退出端口号立即释放
    tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    tcp_server_socket.bind(("", 8989))
    tcp_server_socket.listen(128)
    
    while True:
        # 等待接收客户端的连接请求
        service_client_socket, ip_port = tcp_server_socket.accept()
        print("客户端连接成功:", ip_port)
        # 建立子线程,避免 调用recv函数阻塞
        sub_thread = threading.Thread(target=handle_client_request, args=(service_client_socket, ip_port))
        # 设置守护线程,防止主线程无法退出
        sub_thread.setDaemon(True)
        # 启动子线程
        sub_thread.start()

1.5  多连接服务器开发-select实现

import socket
import select

if __name__ == '__main__':
    tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置端口号复用,让程序退出端口号立即释放
    tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    tcp_server_socket.bind(("", 8989))
    tcp_server_socket.listen(128)
    input_conn =[tcp_server_socket]  #客户端的进来的连接
    while True:
        # 等待接收客户端的连接请求
        rs,ws,es = select.select(input_conn,[],[],0.3)
        for r in rs:
            if tcp_server_socket is r:                  #表示有客户端连接进来
                client_conn, addr= tcp_server_socket.accept()
                input_conn.append(client_conn)
                print("new connection from {}".format(addr))
            else:                                       # 表示客户端有数据
                try:
                    msg = r.recv(2048)
                except socket.error as error:
                    input_conn.remove(r)
                    print("{} disconnect ".format(r.getpeername()))
                    break
                else:
                    if not msg: #消息为空则表示已经断开了连接
                        input_conn.remove(r)
                        print("{} disconnect ".format(r.getpeername()))
                    else:
                        print("Recv msg {} from server ".format(msg))

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值