建立TCP服务
from socket import *
'''
建立TCP服务端
'''
host = ''
buffersize = 1024
port = 9876
addr = (host, port)
'''
AF_INET:IPV4 AF_INET6 IPV6
SOCK_ATREAM: TCP
'''
# 1. Socket对象
tcpServerSocket = socket(AF_INET, SOCK_STREAM)
# 2. 绑定一个端口号
tcpServerSocket.bind(addr)
# 3. 监听端口号
tcpServerSocket.listen()
print('Server port: 9876')
print('等待客户端连接……')
# 4. 等待客户端Socket连接
tcpClientSocket, addr = tcpServerSocket.accept()
print('客户端已经连接', 'addr', '=', addr)
# 5. 读取从客户端发过来的数据
data = tcpClientSocket.recv(buffersize)
print(data.decode('utf8'))
# 6. 向客户端发送数据
tcpClientSocket.send('你好地球人!Hello'.encode(encoding='utf_8'))
# 7. 关闭客户端的Socket连接
tcpClientSocket.close()
# 8. 关闭服务端的Socket连接
tcpServerSocket.close()
服务端接受数据的缓冲区
from socket import *
'''
服务端接收数据的缓冲区
如果客户端发送给服务端的数据过多,需要分多次读取,每次
最多读取缓冲区尺寸的数据,即 bufferSize
'''
bufferSize = 2
addr = ('', 9876)
tcpServerSocket = socket(AF_INET, SOCK_STREAM)
tcpServerSocket.bind(addr)
tcpServerSocket.listen()
print('等待客户端连接')
tcpClientSocket, addr = tcpServerSocket.accept()
print('客户端已连接')
fullDataBytes = b''
while True:
data = tcpClientSocket.recv(bufferSize) # 每次最多读取2字节的数据
fullDataBytes += data
if len(data) < bufferSize: break
print(fullDataBytes)
print(fullDataBytes.decode('ISO-8859-1'))
tcpClientSocket.close()
tcpServerSocket.close()
服务端的请求队列
'''
服务端请求队列
'''
from socket import *
bufferSize = 1024
addr = ('', 9876)
tcpServerSocket = socket(AF_INET, SOCK_STREAM)
tcpServerSocket.bind(addr)
tcpServerSocket.listen(2) # 请求队列,设为2个
print('等待客户端连接')
while True:
tcpClientSocket, addr = tcpServerSocket.accept()
print('客户端已连接', addr)
data = tcpClientSocket.recv(bufferSize)
if data == b'q': break
print(data.decode('utf8'))
tcpClientSocket.send('Hello bor!'.encode(encoding = 'utf-8'))
tcpClientSocket.close()
tcpServerSocket.close()
时间戳服务器
'''
时间戳服务器
'''
from socket import *
from time import ctime
bufferSize = 1024
addr = ('', 9876)
tcpServerSocket = socket(AF_INET, SOCK_STREAM)
tcpServerSocket.bind(addr)
tcpServerSocket.listen()
while True:
print('等待连接')
tcpClientSocket, addr = tcpServerSocket.accept()
while True:
data = tcpClientSocket.recv(bufferSize)
if data == b'q': break
tcpClientSocket.send(ctime().encode(encoding='GBK') + b'\n ' + data)
tcpClientSocket.close()
tcpServerSocket.close()
用Socket实现简易Http服务器
'''
用Socket实现简易HTTP服务器
HTTP请求头
GET POST
GET /html/rfc2616 HTTP/1.1
Host: tools.ietf.org
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
HTTP响应头
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: max-age=604800
Connection: Keep-Alive
Content-Encoding: gzip
Content-Location: rfc2616.html
Content-Type: text/html; charset=UTF-8
Date: Sat, 24 Mar 2018 07:52:47 GMT
ETag: "3d2050-83393-567508dabd73a;56823d38ef5d5"
Expires: Sat, 31 Mar 2018 07:52:47 GMT
Keep-Alive: timeout=5, max=100q
Last-Modified: Tue, 13 Mar 2018 19:49:15 GMT
Server: Apache/2.2.22 (Debian)
Strict-Transport-Security: max-age=3600
TCN: choice
Transfer-Encoding: chunked
Vary: negotiate,Accept-Encoding
X-Clacks-Overhead: GNU Terry Pratchett
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 1; mode=block
'''
from socket import *
import os
def reponseHanders(length):
'''
从文件中读取要返回的Http响应头文本,并将设置返回数据长度为length
'''
f = open('./reponse_headers.txt', 'r')
headersText = f.read()
headersText = headersText % length
return headersText
def filePath(get):
'''
根据http请求头的路径得到服务端的静态文件
'''
if get == '':
return './static' + os.sep + 'index.html'
else:
paths = get.split('/')
s = './static'
for path in paths:
if path.strip() != '':
s += (os.sep + path)
return s
addr = ('', 9876)
buffersize = 1024
tcpServerSocket = socket(AF_INET, SOCK_STREAM)
tcpServerSocket.bind(addr)
tcpServerSocket.listen()
while True:
print('等待客户端连接...')
tcpClientSocket, addr = tcpServerSocket.accept()
print('客户端已经连接, addr = ', addr)
data = tcpClientSocket.recv(buffersize)
data = data.decode('utf-8')
try:
# 获取请求头的第一行
firstline = data.split('\n')[0]
print(firstline)
# 获取请求路径, exp: GET /html/rfc2616 HTTP/1.1
path = firstline.split(' ')[1]
path = filePath(path)
if os.path.exists(path):
file = open(path, 'rb')
content = file.read()
file.close()
else:
content = 'File not found!
'.encode(encoding='utf_8')
rh = reponseHanders(len(content)) + '\r\n'
tcpClientSocket.send(rh.encode(encoding='utf-8') + content)
except Exception as e:
print(e)
tcpClientSocket.close()
tcpServerSocket.close()
客户端Socket
'''
客户端socket
'''
from socket import *
buffersize = 1024
addr = ('localhost', 9876)
tcpClientSocket = socket(AF_INET, SOCK_STREAM)
tcpClientSocket.connect(addr)
while True:
data = input('>>> ')
# 输入空字符串退出
if not data: break
data = data.encode(encoding='utf-8')
tcpClientSocket.send(data)
data = tcpClientSocket.recv(buffersize)
print(data.decode('utf-8'))
UDP时间戳服务器和客户端
'''
UDP时间戳服务器
TCP: 面向连接的协议
UDP: 无连接的协议
'''
from socket import *
from time import ctime
addr = ('', 9876)
buffersize = 1024
udpServerSocket = socket(AF_INET, SOCK_DGRAM)
udpServerSocket.bind(addr)
while True:
print('正在等待消息。。。')
data, addr = udpServerSocket.recvfrom(buffersize)
udpServerSocket.sendto(ctime().encode(encoding='utf-8') + b' ' + data, addr)
udpServerSocket.close()
'''
UDP时间戳客户端
'''
from socket import *
buffersize = 1024
addr = ('localhost', 9876)
udpClientSocket = socket(AF_INET, SOCK_DGRAM)
while True:
data = input('>>> ')
if not data: break
udpClientSocket.sendto(data.encode(encoding='utf-8'), addr)
data, addr = udpClientSocket.recvfrom(buffersize)
if not data: break
print(data.decode('utf-8'))
udpClientSocket.close()
sockerserver类
'''
socketServer TCP时间戳服务器
'''
from socketserver import (TCPServer as TCP, StreamRequestHandler as SRH)
from time import ctime
addr = ('', 9876)
class MyRequestHander(SRH):
def handle(self):
print('客户端已连接, 地址:', self.client_address)
self.wfile.write(ctime().encode(encoding='utf-8') + b' ' + self.rfile.readline())
tcpServer = TCP(addr, MyRequestHander)
tcpServer.serve_forever()
练习
'''
使用UDP Socket编写一个可以计算Python表达式的服务端应用,
然后再编写一个用于测试这个服务端应用的客户端程序。
在客户端程序中输入Python表达式,然后将表达式字符串传到服务端,
服务端执行后,再将结果返回给客户端程序。
'''
'''
服务端
'''
from socket import *
addr = ('', 9876)
buffersize = 1024
udpServerSocket = socket(AF_INET, SOCK_DGRAM)
udpServerSocket.bind(addr)
while True:
print('正在等待消息。。。')
data, addr = udpServerSocket.recvfrom(buffersize)
data = data.decode(encoding = 'utf-8')
print('已接收到表达式:{}, 地址:{}'.format(data, addr))
try:
data = eval(data)
except Exception as e:
print(e)
data = '无效的表达式:{}'.format(data)
data = str(data)
udpServerSocket.sendto(data.encode(encoding='utf-8'), addr)
udpServerSocket.close()
'''
使用UDP Socket编写一个可以计算Python表达式的服务端应用,
然后再编写一个用于测试这个服务端应用的客户端程序。
在客户端程序中输入Python表达式,然后将表达式字符串传到服务端,
服务端执行后,再将结果返回给客户端程序。
'''
'''
客户端
'''
from socket import *
addr = ('localhost', 9876)
buffersize = 1024
udpClientSocket = socket(AF_INET, SOCK_DGRAM)
while True:
expression = input('>>> ')
if not expression: break
udpClientSocket.sendto(expression.encode(encoding='utf_8'), addr)
data, addr = udpClientSocket.recvfrom(buffersize)
if not data: break
print('计算结果:', data.decode('utf-8'))
udpClientSocket.close()