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程序则又不能工作