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队列

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容

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