socket

套接字基础
服务器端代码

#coding:UTF-8
from socket import *
myHost = ''
myPort = 50007
socketobj = socket(AF_INET,SOCK_STREAM)
socketobj.bind((myHost,myPort))
socketobj.listen(5)
while True:
    connection,address = socketobj.accept()
    print('Server connected by ', address)
    while True:
        data = connection.recv(1024)
        print('Client ',data)
        if not data:break
        connection.send(b'Echo=>'+data)
    connection.close()

客户端代码

#coding:UTF-8
from socket import *
serverHost = 'localhost'
serverPort = 50007
message = [b'Hello network world']
socketobj = socket(AF_INET,SOCK_STREAM)
socketobj.connect((serverHost,serverPort))
for line in message:
    socketobj.send(line)
    data = socketobj.recv(1024)
    print('Client recv: ',data)
socketobj.close()

代码解读:

socketobj = socket(AF_INET,SOCK_STREAM)

使用socket模块创建一个套接字对象。里面的参数是固定的AF_INET意味着IP协议地址,SOCK_STREAM意味着TCP传输协议

socketobj.bind((myHost,myPort))

把套接字对象与一个地址关联起来。生成IP地址。主机名通常是一个空字符串

socketobj.listen(5)

开始监听到来的客户端连接,并允许保留五个挂起的请求。在新请求被拒绝之前,传递的值通过操作系统设置到客户端排队请求

connection,address = socketobj.accept()

当请求发生后,accpet调用返回一个全新的套接字对象,在这个套接字对象上,数据可以在连接的客户端发生转移。与客户端的通讯发生在connection上,即新的套接字上。address是连接客户端的互联网地址。

data = connection.recv(1024)

从客户端读取发送的消息,最多1024个字节。当请求结束后会返回一个空字符串。

connection.send(b'Echo=>'+data)

发送新的数据到客户端

客户端的代码差不多

多线程服务器

#coding:utf-8
import time,_thread as thread
from socket import *
myHost = ''
myPort = 50007
socketobj = socket(AF_INET,SOCK_STREAM)
socketobj.bind((myHost,myPort))
socketobj.listen(5)
def now():
    return time.ctime(time.time())
def handleClient(connection):
    time.sleep(3)
    while True:
        data = connection.recv(1024)
        if not data:break
        reply = 'Echo=>%s at %s'%(data,now())
        connection.send(reply.encode())
    connection.close()
def dispatcher():
    while True:
        connection,address = socketobj.accept()
        print('Server connected by ',address,end = ' ')
        print('at',now())
        thread.start_new_thread(handleClient,(connection,))
dispatcher()

dispatcher程序把每个传入的客户端连接请求,指定到新派生的运行handleClient函数的线程中。因此服务器可以同时处理多个客户端,主要的调度程序可以迅速回到顶端。

标准库服务器类


#coding:UTF-8
import socketserver,time
myHost = ''
myPort = 50007
def now():
    return time.ctime(time.time())
class MyClientHandler(socketserver.BaseRequestHandler):
    def handle(self):
        print(self.client_address,now())
        time.sleep(5)
        while True:
            data = self.request.recv(1024)
            if not data:break
            reply = 'Echo=%s at %s'%(data,now())
            self.request.send(reply.encode())
        self.request.close()
if __name__ == '__main__':
    myaddr = (myHost,myPort)
    server = socketserver.ThreadingTCPServer(myaddr,MyClientHandler) #具体处理的子类
    server.serve_forever() #永久开启

基于select的响应服务器
使用select并行处理多个客户端。使用select模块手动在套接字之间多重通道传输

#coding:utf-8
import time
from select import select
from socket import socket, AF_INET,SOCK_STREAM
def now():return time.ctime(time.time())
myHost = ''
myPort = 50007
mainsocks,readsocks,writesocks = [],[],[]
portsock = socket(AF_INET,SOCK_STREAM)
portsock.bind((myHost,myPort))
portsock.listen(5)
mainsocks.append(portsock)
readsocks.append(portsock)
while True:
    readables,writeables,exceptions = select(readsocks,writesocks,[])
    for sockobj in readables:
        if sockobj in mainsocks:
            newsock,address = sockobj.accept()
            print('Connect: ',address,id(newsock))
            readsocks.append(newsock)
        else:
            data = sockobj.recv(1024)
            print('\tgot ',data,'on',id(sockobj))
            if not data:
                sockobj.close()
                readsocks.remove(sockobj)
            else:
                reply = 'Echo=>%s at %s'%(data,now())
                sockobj.send(reply.encode())

select调用细节
从形式上看,select可以调节可选择对象的三种列表(输入源、输出源和特殊条件)

select.select(rlist, wlist, xlist[, timeout])

rlist,wlist,xlist分别为需要异步处理的读socket队列, 写socket队列(一般不用), 和错误socket队列, 返回事件的读写和错误socket队列

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 大纲 一.Socket简介 二.BSD Socket编程准备 1.地址 2.端口 3.网络字节序 4.半相关与全相...
    VD2012阅读 7,282评论 0 5
  • 《UNIX 网络编程卷一:套接字联网API》笔记 套接字 套接字编程接口,是在 TCP/IP 协议族中,应用层进入...
    超net阅读 11,127评论 2 13
  • 从武汉回来转眼就快一个星期了,今天是报名参加硕士毕业典礼的日子。时间过得真快,一个星期就这样恍然而失,最近...
    _荷包蛋_阅读 4,844评论 1 13