3W作业_极简交互式网络笔记
本周整体任务概述:
- 在上周开发基础上, 完成 极简交互式笔记的网络版本
- 需求如下:
- 每次运行时合理的打印出过往的所有笔记
- 一次接收输入一行笔记
- 在服务端保存为文件:
- 在所有访问的客户端可以获得历史笔记
- 支持多个客户端同时进行笔记记录
- 时限: 2wd4~3wd3
- 发布: 发布到各自仓库的 _src/om2py3w/3wex0/ 目录中
- 指标:
- 包含软件使用说明书: README.md
- 能令其它学员根据说明书,运行系统,完成所有功能
- 备选的:
- 如果有余力!-)
- 请尝试思考,是否能保存笔记的客户端来源?
- 并在合适的情景中输出?
- 进一步的,能根据客户端不同,要求输出不同客户端提交的笔记嘛?
把芝麻星提到的知识点过一遍
socker 是计算机用于通信的接口,用于client 跟server 建立一个socker接口进行数据传输
- C/S 架构系统
client 跟server 的结构模式,利用两端的环境进行任务分配
- 什么是 DUP 协议
全称User Datagram Protocol ,把网络的数据压缩成数据的形式,提供信息的传输服务。
系统:mac 10.10.5
Pythone版本:Python 2.7.10
试着把帮助文档的两个例子运行下,只是起到对接作用,并没有传输数据的功能,需要一个能接收数据,一个能传输数据的参数。
把例子用到参数功能了解下
- socket.bind 把socket绑定到指定的端口跟地址
- socket.listen 监听链接数量
- socket.accept 允许链接
- socket.connect 链接服务器sokcet
- socket.sendall 传输数据跟服务器socket
- socket.recv 接收socket数据
帮助文档找到 sendto 用于把数据传送到服务端的socker,再用recv参数接受socket传送过来的数据,先从修改例子入手。
server端
import socket
HOST = 'localhost'
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
print 'connecting.......'
s.bind((HOST, PORT))
while 1:
data, addr = s.recvfrom(1024)#关键参数recvfrom,接收socket传过来的数据
print data
s.close()
client端
import socket
HOST = 'localhost'
PORT = '50007'
w = raw_input('>>>>')
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.sendto(w, ('localhost', 50007)) #关键参数sendto,数据传到服务端socket。
开始服务端使用的是recv参数报错,查了下改用 socket.recvfrom 参数试试,用于接受来源地址socker数据
data, addr = s.recv(1024)
ValueError: too many values to unpack
各种尝试,数据是能从client端传送到服务端了,但每次只能传输一次,就断线了,与目标功能还要很大的差距,还需解决
- 如何循环输入
- 如何服务端本地保存一份
- 如何把1w作业结合进来
加入while 参数实现循环,客户利用s.sendto 传输数据给服务端,用s.recvfrom来接受读取服务端传回来的数据,而服务端再通过s.recvfrom来接受客户端传回来的命令,用s.sendto来把输出传送给客户端。
服务端
while True: #加入while 起到循环作用
data, addr = s.recvfrom(4097) #接受客户端传送的命令
if data in 'q':
pass
elif data in 'r':
f = open('mydiary.txt', 'r') #当客户端传回r,调用阅读本地的mydiry.txt文档
txt = f.read()
s.sendto(txt, addr) #并把读取本地文档数据传送给client端
elif data not in 'r' or 'q': #如果客户端传来非r or q ,data写入本地文档
w = open('mydiary.txt', 'a+')
w.write("\n" + data)
w.close
print data
elif not data:
客户端
while True: #加入while 起到循环作用
while True:
data = raw_input('>>>') #把输入的数据定义成data
if data in 'r':
s.sendto(data, host_port)
txt, server = s.recvfrom(4096)#读取服务端的mydiary.txt文档
print txt
elif data in 'q':
print 'bye'
break
else:
s.sendto(data, host_port)
s.close()
20151105优化下代码,跟一些细节
添加 upper() 输入命令不区分大小写,
添加time
- 服务端
while True:
data, addr = s.recvfrom(4097)
print "客户端IP来源 %s, %s" %addr
if data.upper() in ['R', 'READ']:
f = open('mydiary.txt', 'r')
txt = f.read()
print '---读取历史日记---'
s.sendto(txt, addr)
elif data not in '':
w = open('mydiary.txt', 'a+')
w.write("\n" + data)
w.close
print data
elif not data:
break
- 客户端
while True:
t = time.strftime('%Y-%M-%D')
data = raw_input(t + '>>> ')
if data.upper() in ['R', 'READ']:
s.sendto(data, host_port)
txt, server = s.recvfrom(4096)
print txt
elif data.upper() in ['H', 'HLEP', '?']:
print '''
+ r/R/read/READ - 读取历史日记
+ q/Q/exit/EXIT/quit/QUIT - 退出
'''
elif data.upper() in ['Q', 'EXIT', 'QUIT']:
print '退出'
break
else:
s.sendto(data, host_port)
更新20151104
更新20151106 代码