zoukankan      html  css  js  c++  java
  • python利用select实现的Socket Server

    # 利用python的select模块实现简单的Socket Sever

    #实现多用户访问,再次基础上可以实现FTP Server应用程序

    # 发布目的,在于解决了客户端强行终止时,服务器端也跟着程序终止

    # 程序的关键在:读就是读,写就是写 ,不要读写混着来

    # 代码如下:

    Server

     1 __author__ = 'Stone'
     2 # -*- coding: UTF-8 -*-
     3 # !/usr/bin/env python3
     4 import socket
     5 import queue
     6 import select
     7 HOST = '0.0.0.0'
     8 PORT = 8000
     9 s = socket.socket()
    10 s.bind((HOST,PORT))
    11 s.listen(500)
    12 # 设定关闭程序后,能马上释放服务器的端口,供后续程序使用
    13 s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    14 s.setblocking(0) # 设置为非阻塞模式
    15 # 设置列表,新建、发送、异常
    16 inputs = []
    17 outputs = []
    18 #exceptions = []
    19 # 存放信息
    20 msg_dic = {}
    21 inputs.append(s)  # 把自身加进去,侦听是否有新连接
    22 while True:
    23     readable,writable,exceptional = select.select(inputs,outputs,inputs)  # select 会阻塞socket
    22
    25     for r in readable:
    26         if r is s:
    27             # 说明有新连接过来
    28             conn,addr = s.accept()
    29             print("新连接:",addr)
    30             conn.setblocking(0) # 把单个连接也设置为非阻塞模式,比如:某个连接接收的文件比较大,将会一直占用着(别的程序没机会处理);设置为非阻塞后,可以等着下次for循环继续接收
    31             inputs.append(conn)
    32             msg_dic[conn] = queue.Queue()  # 为每个连接创建消息队列
    33         else:
    34             # 说明有连接是活动的
    35                 try:
    36                     data = r.recv(1024)
    37                     if data:
    38                         print("接收到了数据:",data.decode('utf-8'))
    39                         # 放进消息队列
    40                         msg_dic[r].put(data)
    41                         if r not in outputs:
    42                             outputs.append(r)  # 并放入发送数据列表
    43                     else:
    44                         # 连接断开
    45                         print("客户端断开连接")
    46                         if r in outputs:
    47                             outputs.remove(r)
    48                         inputs.remove(r)
    49                         del msg_dic[r]
    50                 except socket.error:     # 解决问题(出现客户端异常断开,服务器也跟着断开),后面不做任何处理,留给exceptional做处理
    51                     pass
    52 
    53     for w in writable:
    54         try:
    55             send_msg = msg_dic[w].get_nowait()
    56         except queue.Empty:
    57             print("client [%s]"% w.getpeername()[0],"queue is empty...")
    58             outputs.remove(w)
    59         else:
    60             print("sending message to [%s]"% w.getpeername()[0],send_msg)
    61             w.send(send_msg)
    62             outputs.remove(w)  # 防止再次执行时,发生empty的异常
    63 
    64     for e in exceptional:
    65         if e in outputs:
    66             outputs.remove(e)
    67         inputs.remove(e)
    68         e.close()
    69         del msg_dic[e]
    70 s.close()

    Client:
     1 __author__ = 'Stone'
     2 # -*- coding: UTF-8 -*-
     3 # !/usr/bin/env python3
     4 import socket
     5 HOST = 'localhost'
     6 PORT = 8000
     7 s_client = socket.socket()
     8 s_client.connect((HOST,PORT))
     9 while True:
    10     data = input('>>:').strip()
    11     if not data:
    12         continue
    13     s_client.send(data.encode('utf-8'))
    14     recv = s_client.recv(1024)
    15     print(recv)
    16     #break      # 测试,作为客户端自动离开
    17 s_client.close()
    
    
  • 相关阅读:
    ubuntu播放器
    第一次装ubuntu 没root密码时
    web服务器记录
    socket udp编程步骤
    nfs服务器配置
    带线程函数编译条件
    linux使用一个刚编译驱动方法
    tiny6410_led驱动Makefile
    java-设计模式-外观模式
    java-实现一个简单的java Web容器
  • 原文地址:https://www.cnblogs.com/shihongkuan/p/9122567.html
Copyright © 2011-2022 走看看