python核心编程(第三版) 第二章 -网络编程

版权声明:本文为博主原创文章,欢迎转载。 https://blog.csdn.net/fww330666557/article/details/82873702

一、TCP

1、服务端

#!/usr/bin/env python3
#-*- coding:utf-8 -*-

'''
python3 TCP 时间戳服务器
'''
__author__ = 'TaoGuan'

from socket import *
from time import ctime

# HOST变量是空白的,这是对bind()方法的标识,表示它可以使用任何可用的地址。
HOST = ''
# 指定未被使用或被系统保留的端口号
PORT = 21567 
# 将缓冲区大小设置为1K,可以根据网络性能和程序需要改变
BUFSIZ = 1024
# 使用元组保存主机名和端口号
ADDR = (HOST, PORT)

# 分配TCP服务套接字
tcpSerSock = socket(AF_INET, SOCK_STREAM)
# 将套接字绑定到服务器地址
tcpSerSock.bind(ADDR)
#开启TCP监听器的调用,listen函数的参数是在连接被转接或拒绝之前,传入连接请求的最大数
tcpSerSock.listen(5)

while True:
    print('waiting for connection...')
    # 注意,accept函数返回了两个值
    tcpCliSock, addr = tcpSerSock.accept()
    print('...connection:', addr)
    while True:
        # recv返回值为字节对象,大小不超过BUFSIZ
        data = tcpCliSock.recv(BUFSIZ)
        # 消息空白,意味着客户端已经退出
        if not data:
            break
        # 得到了来自客户端的数据,将其格式化并返回
        tcpCliSock.send(('[%s] %s' % (ctime(),str(data, encoding = "utf-8"))).encode())
    # 关闭当前客户端连接
    tcpCliSock.close()
# 对于服务器来说,这句永远不会执行
tcpSerSock.close()

2、客户端

#!/usr/bin/env python3
#-*- coding:utf-8 -*-

'''
python3 TCP 时间戳客户端
'''
__author__ = 'TaoGuan'

from socket import *
from time import ctime

HOST = '127.0.0.1' # or 'localhost'
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST, PORT)

# 分配TCP客户端套接字
tcpCliSock = socket(AF_INET, SOCK_STREAM)
# 连接服务器
tcpCliSock.connect(ADDR)
while True:
    data = input('> ')
    # 用户没有输入
    if not data:
        break
    # 需要将str转换为字节
    tcpCliSock.send(data.encode('utf-8'))
    data = tcpCliSock.recv(BUFSIZ)
    # 服务器终止且对recv方法调用失败
    if not data:
        break
    print(data.decode())
tcpCliSock.close()

3、运行

客户端:

192:hellopython fww$ python3 tsTclnt3.py
> 1
[Fri Sep 28 01:28:05 2018] 1
> abcdefg
[Fri Sep 28 01:28:22 2018] abcdefg
> 你好
[Fri Sep 28 01:28:30 2018] 你好
> 成功了,哈哈
[Fri Sep 28 01:28:38 2018] 成功了,哈哈
> 
192:hellopython fww$ python3 tsTclnt3.py
> 再次输入
[Fri Sep 28 01:29:17 2018] 再次输入
> 
192:hellopython fww$ 

服务端:

# 启动服务器后进入等待状态
waiting for connection...  
# 客户端第一次连接 			
...connection: ('127.0.0.1', 62363)	 
# 客户端断开
waiting for connection...
# 客户端第二次连接				
...connection: ('127.0.0.1', 62368) 	
# 客户端再次断开
waiting for connection...				

二、UDP

1、服务端

#!/usr/bin/env python3
#-*- coding:utf-8 -*-

'''
python3 UDP 时间戳服务器
'''
__author__ = 'TaoGuan'

from socket import *
from time import ctime

HOST = ''
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST, PORT)

udpSerSock = socket(AF_INET, SOCK_DGRAM)
udpSerSock.bind(ADDR)
while True:
    print('waiting for message...')
    data, addr = udpSerSock.recvfrom(BUFSIZ)
    udpSerSock.sendto(('[%s] %s' % (ctime(),str(data, encoding = "utf-8"))).encode(), addr)
    print('...received from and returned to:',addr)
udpSerSock.close()

2、客户端

#!/usr/bin/env python3
#-*- coding:utf-8 -*-

'''
python3 UDP 时间戳客户端
'''
__author__ = 'TaoGuan'

from socket import *
from time import ctime

HOST = '127.0.0.1'
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST, PORT)

udpCliSock = socket(AF_INET, SOCK_DGRAM)
while True:
    data = input('> ')
    if not data:
        break
    udpCliSock.sendto(data.encode(), ADDR)
    data, ADDR = udpCliSock.recvfrom(BUFSIZ)
    if not data:
        break
    print(data.decode('utf-8'))
udpCliSock.close()

3、运行

1、客户端

192:hellopython fww$ python3 tsUclnt3.py
> 123
[Fri Sep 28 12:11:51 2018] 123
> 你好
[Fri Sep 28 12:12:03 2018] 你好
> 成功了
[Fri Sep 28 12:12:09 2018] 成功了
> 哈哈
[Fri Sep 28 12:12:12 2018] 哈哈
> 
192:hellopython fww$ python3 tsUclnt3.py
> 我又来了
[Fri Sep 28 12:12:34 2018] 我又来了
> 我要走了
[Fri Sep 28 12:12:41 2018] 我要走了
> bye
[Fri Sep 28 12:12:50 2018] bye
> 
192:hellopython fww$ 

2、服务端:

waiting for message...
...received from and returned to: ('127.0.0.1', 56019)
waiting for message...
...received from and returned to: ('127.0.0.1', 56019)
waiting for message...
...received from and returned to: ('127.0.0.1', 56019)
waiting for message...
...received from and returned to: ('127.0.0.1', 56019)
waiting for message...
...received from and returned to: ('127.0.0.1', 62783)
waiting for message...
...received from and returned to: ('127.0.0.1', 62783)
waiting for message...
...received from and returned to: ('127.0.0.1', 62783)
waiting for message...

三、socketserver

1、socketserver TCP时间戳服务器

#!/usr/bin/env python3
#-*- coding:utf-8 -*-

'''
python3 socketserver TCP 时间戳服务器
'''
__author__ = 'TaoGuan'

from time import ctime
from socketserver import (TCPServer as TCP, StreamRequestHandler as SRH)

HOST = ''
PORT = 21567    
ADDR = (HOST, PORT)
class MyRequestHandler(SRH):
    def handle(self):
        data = '[%s] %s' % (ctime(), str(self.rfile.readline(), encoding = "utf-8"))
        print('...connected from :', self.client_address)
        self.wfile.write(data.encode('utf-8'))

tcpServ = TCP(ADDR, MyRequestHandler)
print('waiting for connection...')
tcpServ.serve_forever()

MyRequestHandler作为StreamRequestHandler的一个子类,并重写了它的handle()方法,该方法在基类中默认没有任何行为:

def handle(self):
	pass

当收到一个来自客户端的消息时,handle()方法就会被调用。StreamRequestHandler类将输入输出套接字看作类似文件的对象,因此我们将使用readline()来获取客户端的消息,并使用write()将字符串发送回客户端。因此在客户端和服务端代码中,需要额外的回车和换行符。实际上在代码中你并看不到它们,因为我们只是重用来自客户端的符号。

2、socketserver TCP时间戳客户端

#!/usr/bin/env python3
#-*- coding:utf-8 -*-
'''
python3 socketserver TCP 时间戳客户端
'''

__author__ = 'TaoGuan'

from socket import *

HOST = 'localhost'
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST, PORT)

while True:
    tcpCliSock = socket(AF_INET, SOCK_STREAM)
    tcpCliSock.connect(ADDR)
    data = input('> ')
    if not data:
        break
    tcpCliSock.send(('%s\r\n' % data).encode('utf-8'))
    data = tcpCliSock.recv(BUFSIZ)
    if not data:
        break
    print(str(data, encoding = "utf-8"))
    tcpCliSock.close()

socketserver请求处理程序的默认行为是接受连接、获取请求、然后关闭连接。因此,我们不能在应用程序整个执行过程中都保持连接,因此,每次向服务器发送消息时都要创建一个新的套接字。

3、运行

客户端:

192:hellopython fww$ python3 tsTclntSS.py
> 123
[Fri Sep 28 21:57:18 2018] 123

> hello
[Fri Sep 28 21:57:24 2018] hello

> 你好
[Fri Sep 28 21:57:30 2018] 你好

> 太好了,我终于成功了!
[Fri Sep 28 21:57:35 2018] 太好了,我终于成功了!

服务器:

waiting for connection...
...connected from : ('127.0.0.1', 55484)
...connected from : ('127.0.0.1', 55488)
...connected from : ('127.0.0.1', 55489)
...connected from : ('127.0.0.1', 55490)
...connected from : ('127.0.0.1', 55493)

四、Twisted框架介绍

Twisted是一个完整的事件驱动网络框架。利用它,既能使用也能开发完整的异步网络应用程序和协议。
Twisted的大部分功能都存在于它的类中。

1、创建Twisted Reactor TCP服务器

#!/usr/bin/env python3
#-*- coding:utf-8 -*-

'''
python3 Twisted Reactor TCP 时间戳服务器
'''
__author__ = 'TaoGuan'

from twisted.internet import protocol, reactor
from time import ctime

PORT = 21567
class TSServProtocol(protocol.Protocol):
    def connectionMade(self):
        clnt = self.clnt = self.transport.getPeer().host
        print('...connected from:', clnt)
    def dataReceived(self, data):
        self.transport.write(('[%s] %s' % (ctime(), str(data, encoding = "utf-8"))).encode())
factory = protocol.Factory()
factory.protocol = TSServProtocol
print('waiting for connetion...')
reactor.listenTCP(PORT, factory)
reactor.run()

2、创建Twisted Reactor TCP客户端

#!/usr/bin/env python3
#-*- coding:utf-8 -*-

'''
python3 Twisted Reactor TCP 时间戳客户端
'''
__author__ = 'TaoGuan'

from twisted.internet import protocol, reactor

HOST = 'localhost'
PORT = 21567

class TSClntProtocol(protocol.Protocol):
    def sendData(self):
        data = input('> ')
        if data:
            print('...sending %s ...' % data)
            self.transport.write(data.encode('utf-8'))
        else:
            self.transport.loseConnection()
    
    def connectionMade(self):
        self.sendData()
    
    def dataReceived(self, data):
        print(data.decode())
        self.sendData()

class TSClntFactory(protocol.ClientFactory):
    protocol = TSClntProtocol
    clientConnectionLost = clientConnectionFailed = lambda self, connector, reason: reactor.stop()

reactor.connectTCP(HOST, PORT, TSClntFactory())
reactor.run()

3、执行

1、客户端

192:hellopython fww$ python3 tsTclntTW3.py
> 1
...sending 1 ...
[Sat Sep 29 00:51:00 2018] 1
> hello
...sending hello ...
[Sat Sep 29 00:51:15 2018] hello
> 你好
...sending 你好 ...
[Sat Sep 29 00:51:24 2018] 你好
> 太好了,我成功了 ,哈哈
...sending 太好了,我成功了,哈哈 ...
[Sat Sep 29 00:51:42 2018] 太好了,我成功了,哈哈

2、服务器

waiting for connetion...
...connected from: 127.0.0.1

猜你喜欢

转载自blog.csdn.net/fww330666557/article/details/82873702