Python全栈学习笔记---网络编程(三)

一、客户端/服务器架构

客户端:因特定需求联系服务器,并发送必要的数据,然后等待服务器响应,最后完成请求或给出故障原因。对服务进行一次性请求。

服务器:一组硬件和软件,为一个或多个客户端服务。存在的唯一目的就是等待客户端请求,并响应然后等待更多请求。服务器无限运行,并不断处理请求

  • 硬件客户端/服务器架构,例:打印机服务器、文件服务器
  • 软件客户端/服务器架构,例:Web服务器、数据库服务器、窗体服务器

二、套接字(socket):通信端点,监听请求

套接字地址:(主机名,端口号)

UDP:成本低廉,不需大量的维护,例如:使用面向连接的协议

1、socket模块函数

创建套接字

1 import socket
2 tco_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
3 udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

缩短代码:

1 from socket import * #将socket模块引入命名空间
2 tco_socket = socket(AF_INET, SOCK_STREAM)
3 udp_socket = socket(AF_INET, SOCK_DGRAM)

 

1.1、套接字的内置方法:

 

 1.2、创建TCP服务器/客户端

1.2.1、创建TCP服务器

 

 1 '''
 2     创建TCP服务器,创建TCP服务器,接受客户端发送的字符串,并将其打上时间戳并返回给客户端
 3 '''
 4 from socket import *
 5 from time import ctime
 6 
 7 HOST = '' #主机名
 8 PORT = 21567 #端口号
 9 BUF_SIZE = 1024 #缓冲区大小
10 ADDR = (HOST, PORT)
11 
12 tcp_sersock = socket(AF_INET, SOCK_STREAM)
13 tcp_sersock.bind(ADDR) #套接字绑定服务器地址
14 tcp_sersock.listen(5) #传入连接请求的最大数
15 try:
16     while True:
17         print('Waiting for connection...')
18         tcp_clisock, addr = tcp_sersock.accept() #接受客户端连接,返回客户端套接字,空出原始服务器套接字,使其可等待其它客户端请求
19         print('...connected from:', addr)
20 
21         while True:
22             data = tcp_clisock.recv(BUF_SIZE).decode() #客户端套接字接受TCP消息,当一方关闭连接或向对方发送一个空字符串,连接关闭
23             if not data:
24                 break
25             tcp_clisock.send(('[%s] %s ' % (ctime(),  data)).encode())
26         tcp_clisock.close() #关闭临时客户端套接字
27 except ValueError:  #传入一个调用者不期望的值,即使值的类型是正确的
28     tcp_sersock.close()     #关闭服务端套接字,但一般服务器应无限循环运行,若服务器要实现智能退出方案,建议使用close()

 

 

 

 

 

 

注:

  • 若支持IPv6,创建套接字时为AF_INET6
  • 优雅地退出和调用服务器close()方法,使用try-except方法

 1.2.2、创建TCP客户端

'''
    创建TCP客户端, 连接到服务器,并以逐行数据的形式提示用户,服务器则返回加入时间戳的相同诗句,并通过客户端展示给用户
'''
from socket import *

HOST = 'localhost' #服务器主机名 or'127.0.0.1 '
PORT = 21567  #服务器端口号
BUF_SIZE = 1024 #缓冲区大小
ADDR = (HOST, PORT)

tcp_clisock = socket(AF_INET, SOCK_STREAM)
tcp_clisock.connect(ADDR) #创建到服务器的连接

while True:
    data = input('>')
    if not data:
        break
    tcp_clisock.send(data.encode())
    data = tcp_clisock.recv(BUF_SIZE).decode()
    if not data:
        break
    print(data)
tcp_clisock.close()

 

注:注意编码方式的转换

1.2.3、 执行TCP服务器和客户端

先执行服务器再执行客户端,若修改主机名则服务器在其他电脑上运行

>>>服务器端:
Waiting for connection... ...connected from: ('127.0.0.1', 45529)
>>>客户端:

>lll
[Sun Mar 4 16:27:47 2018] lll

 

1.3、创建UDP服务器和客户端

1.3.1、创建UDP服务器

 1 '''
 2 创建UDP服务器,接受客户端发来的消息,并加入时间戳前缀的该消息返回给客户端
 3 '''
 4 
 5 from socket import *
 6 from time import ctime
 7 
 8 HOST = ''
 9 PORT = 21567
10 BUF_SIZE = 1024
11 ADDR = (HOST, PORT)
12 
13 udp_sersock = socket(AF_INET, SOCK_DGRAM)
14 udp_sersock.bind(ADDR)
15 try:
16     while True:
17         print('Waiting for message...')
18         data, addr = udp_sersock.recvfrom(BUF_SIZE)
19     
20         udp_sersock.sendto(('[%s] %s ' % (ctime(), data.decode())).encode(), addr)
21         print('...received from and returned to:', addr)
22 except ValueError:
23     udp_sersock.close()

 

 

 1.3.2创建UDP客户端

 1 '''
 2 创建UDP客户端,提示用户输入发送到服务器的消息,并接受服务器加入时间戳的消息,然后显示给用户
 3 '''
 4 
 5 from socket import *
 6 
 7 HOST = 'localhost'
 8 PORT = 21567
 9 BUF_SIZE = 2014
10 ADDR = (HOST, PORT)
11 
12 upd_clisock = socket(AF_INET, SOCK_DGRAM)
13 
14 while True:
15     data = input('>')
16     if not data:
17         break
18     upd_clisock.sendto(data.encode(), ADDR)
19     data, ADDR = upd_clisock.recvfrom(BUF_SIZE)
20     if not data:
21         break
22     print(data.decode())
23 upd_clisock.close()

 

 

 

 

 

 

posted @ 2018-07-22 10:18  Stranger115  阅读(131)  评论(0编辑  收藏  举报