3w LAN日记交互
了解了C/S是如何通过socket连接工作的,但对于本期课程如何实现尚未有很清楚的认识,是否可以和上周的程序配合?
搜索networking python
找到了一个外国人的教程,Python Advanced Tutorial 6.5 - Networked Chat
用包含 recvfrom 的receiving函数,觉得有点靠谱了,但是我上周的程序是用的class,怎么结合呢?这个code提到几个东西不明白,threading,研究一下
- threading 是用来启动与主程序同时运行的函数
- Lock 可以用来决定命令顺序?还是没太弄明白
看完 multithread这一课,也许这就是大妈用来实现实时更新的命令
https://www.youtube.com/watch?v=3JeHWl0cjJ8,提到了scapy
想法超出了自己的能力范围。。
此时面对两大难题,第一就是大妈的两个客户端不连服务端也能传输信息的梗,第二个就是如何与上期代码结合。此时自己无法跨越,先把基本的功能实现。
修改C/S教程出错
server: 读历史信息,录入即时信息
update_lines = open('daily.log', 'a')
update_lines.write(date + '/n')
录入不得
date >>> data
client: 连接是自动读历史信息
server:
if addr not in clients: # add new client addr into the list
clients.append(addr)
for client in clients:
s.sendto(lines, client)
client:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # create a socket
s.bind((host, port)) s.setblocking(0)
lines, addr = s.recvfrom(1024) print lines
socket.error: [Errno 35] Resource temporarily unavailable
自主写代码
又看了一遍https://www.youtube.com/watch?v=LJTaPaFGmM4 发现发出和接收都有一一对应的关系,而且基本可以自己写一个这样的程序了.
尝试1: 1个client录入信息到server中,打开时显示历史信息
在写程序时,发现抄袭版本的send(addr)中的addr已经被自己改动
server:
# encoding: UTF-8
import socket
def send_read():
opened_lines.seek(0)
lines = opened_lines.read()
s.sendto(lines + '\n', addr)
# 1 creat a socket and bind
host = '127.0.0.1'
port = 5000
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))
# receive from client for sending log info. and ask for name
data, addr = s.recvfrom(1024)
name = str(data)
# 2 send the history log to client
opened_lines = open('daily.log', 'a+')
send_read()
# 3 receive data from client, using while function, if data = r, back to 2
Quitting = False
while not Quitting:
data, addr = s.recvfrom(1024)
if 'quit' in str(data):
Quitting = True
elif 'read' in str(data):
read()
else:
opened_lines.write('\n' + str(data))
print name + ": " + str(data)
opened_lines.close()
s.close()
client:
import socket
server = ('127.0.0.1', 5000)
host = '127.0.0.1'
port = 0
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))
#send name and recv log content
name = raw_input('Username ->')
s.sendto(name, server)
data, addr = s.recvfrom(1024) # 注释
print str(data)
# while loop
quitting = False
while not quitting:
in_put = raw_input(str(name) + '-> ')
if in_put == 'q':
quitting = True
else:
s.sendto(in_put, server)
data, addr = s.recvfrom(1024)
print str(data)
s.close()
注释: 1. 等号左边只有一个参数时,print str(data)出现中文编译的乱码:xe5\xb0\x8f\xe8\xaf。。。
问题
log内容呈现在client后,新输入的信息无法反馈
- 猜测:有可能是client发送信息后,无法直接接收信息,同时server也不能接受信息后马上传送
反复测试server.py 和 client.py, 发现只有第一次从客户端传送的信息能够录入,而且client没有第二次的raw_input提示符
反复研究代码后发现是由于每次client接收信息都要you一个发出信息的指令对应于是在server的循环中加入了sendto
while not Quitting:
data, addr = s.recvfrom(1024)
if str(data) == 'quit':
s.sendto('', addr)
Quitting = True
elif str(data) == 'read':
send_read()
else:
opened_lines.write('\n' + str(data))
s.sendto(str(data) + '\n', addr)
print name + ": " + str(data)
bug: quit之后如果输入的不是q程序则又不能工作