Python核心编程习题之二——网络编程

1. 面向连接的套接字和无连接的套接字之间的区别是什么?

  • 套接字是计算机网络数据结构,套接字最初是为同一主机上的应用程序所创建,使得主机上的不同应用程序可以相互通信,这就是所谓的进程间通信(Inter Process Communication,IPC)
面向连接的套接字 无连接的套接字
在通信之前必须建立连接 在通信之前不需要建立连接
序列化的,可靠的不重复的数据交付 无法保证顺序性,可靠性或重复性,减少以一定的开销
没有记录边界 保存了记录边界
每条信息可以拆分成多个片段,并且每一个消息片段都能确保到达目的地,然后将他么按顺序组合在一起。 消息是以整体发送的。
传输控制协议(TCP) 用户数据协议(UDP)

2. 客户端/服务器架构

  • 服务器就是一系列硬件或软件,为一个或多个客户端(服务的用户)提供所需的“服务”。其存在的目的就是等待客户端的请求,并响应他们(提供服务),然后等待更多的请求。

3. TCP和UDP之中,哪种类型的服务器接收连接,并将他们转换到独立的套接字进行客户端通信

TCP

4. 更新TCP(tsTclnt.py)和UDP(tsUclnt.py)客户端,以使得服务器名称无须硬编码到应用程序中。

if __name__ == '__main__':
    opts, args = getopt.getopt(sys.argv[1:],'',['host=','port='])
    for op, value in opts:
        if op == '--host':
            HOST = value
        elif op == '--port':
            PORT = value

在程序中加入这段代码,可以通过输入命令来进行指定的host和port

5. 编写TCP客户端/服务器程序,使得服务器能够识别以下命令:

  • date 服务器返回当前日期/时间戳,即time.ctime()
  • os 获取操作系统信息(os.name)
  • ls 列出当前目录文件清单(提示:os.listdir()列出一个目录,os.curdir()是当前目录)
tcp_server.py(服务器端代码)
import socket
from time import ctime
import os
import re

HOST = ''
PORT = 50006
ADDR = (HOST, PORT)

#获取指定路径的文件列表,默认为当前文件列表
def list_dir(path = os.curdir):
    files = os.listdir(path)
    filenames = []
    for file in files:
        filenames.append(file)
    return '\n'.join(filenames)

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind(ADDR)
    s.listen(5)
    while True:
        conn, addr = s.accept()
        with conn:
            print('Connected by', addr)
            while True:
                data = conn.recv(1024)
                s_data = ''
                if not data: break
                data = data.decode('utf-8')
                #判断指令为time
                if data == 'time':
                    s_data = '[%s]'%ctime()
                #判断指令为os
                elif data == 'os':
                    s_data = '[%s]'%os.name
                else:
                    #判断指令为ls
                    if data == 'ls':
                        s_data = list_dir()
                    else:
                        #判断指令为ls path
                        patt = 'ls\s([^\s]+)'
                        m = re.match(patt,data)
                        if m:
                            path = m.group(1)
                            if os.path.exists(path):
                                s_data = list_dir(path)
                            else:
                                s_data = 'not exist path'
                        else:
                            s_data = 'this is no order' + data
                conn.send(s_data.encode('utf-8'))
tcp_clnt.py(客户端代码)
import socket

HOST = 'localhost'
PORT = 50006
ADDR = (HOST, PORT)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect(ADDR)
    while True:
        data = input('>>> ')
        if not data:break
        s.send(data.encode('utf-8'))
        data = s.recv(1024)
        if not data:break
        data = data.decode('utf-8')
        print(data)

6. 半双工聊天

hdserver.py(半双工聊天服务器)
from socket import *

HOST = ''
PORT = 50006
BUFSIZE = 1024
ADDR = (HOST, PORT)

with socket(AF_INET, SOCK_STREAM) as s:
    s.bind(ADDR)
    s.listen(5)
    while True:
        conn, addr = s.accept()
        with conn:
            print('connected by ',addr)
            while True:
                data = conn.recv(BUFSIZE)
                if not data:break
                print('from:',data.decode('utf-8'))
                data = input('to: ')
                if not data:break
                conn.send(data.encode('utf-8'))
hdclnt.py(半双工聊天客户端)
from socket import *

HOST = 'localhost'
POST = 50006
BUFSIZE = 1024
ADDR = (HOST, POST)

with socket(AF_INET, SOCK_STREAM) as s:
    s.connect(ADDR)
    while True:
        data = input('to: ')
        if not data:break
        s.send(data.encode('utf-8'))
        data = s.recv(BUFSIZE)
        print('from: ',(data.decode('utf-8')))

7. 全双工聊天

fdserver.py(全双工服务器)
from socket import *
from select import *
import sys

HOST = ''
PORT = 50007
BUFSIZE = 1024
ADDR = (HOST, PORT)

with socket(AF_INET, SOCK_STREAM) as tcp_server:
    tcp_server.bind(ADDR)
    tcp_server.listen(5)
    inpu = [tcp_server, sys.stdin]
    while True:
        conn, addr = tcp_server.accept()
        inpu.append(conn)
        while True:
            r_list, w_list,e_list = select(inpu,[],[])
            for s in r_list:
                if s == conn:
                    data = conn.recv(BUFSIZE)
                    if not data: break
                    print(data.decode('utf-8'))
                else:
                    data = input('>>> ')
                    if not data: break
                    conn.send(data.encode('utf-8'))
fdclnt.py(全双工聊天客户端)
from socket import *
from select import *
import sys

HOST = 'localhost'
POST = 50007
BUFSIZE = 1024
ADDR = (HOST, POST)

with socket(AF_INET, SOCK_STREAM) as tcp_clnt:
    tcp_clnt.connect(ADDR)
    inpu = [tcp_clnt,sys.stdin]
    while True:
        r_list, w_list, e_list = select(inpu,[],[])
        for s in r_list:
            if s == tcp_clnt:
                data = tcp_clnt.recv(BUFSIZE)
                if not data: break
                print((data.decode('utf-8')))
            else:
                data = input('>>> ')
                if not data:break
                tcp_clnt.send(data.encode('utf-8'))

8. 多用户全双工聊天

mfd_server(多用户全双工聊天服务器端)
from socket import *
import threading

HOST = ''
PORT = 21568
BUFSIZE = 1024
ADDR = (HOST, PORT)

conns = []

#当收到消息时,向其他用户发送消息
def deal_conn(conn):
    while True:
        data = conn.recv(BUFSIZE)
        if not data:break
        for c in conns:
            if c != conn:
                c.send(data)

with socket(AF_INET, SOCK_STREAM) as server:
    server.bind(ADDR)
    server.listen(10)
    while True:
        conn, addr = server.accept()
        #向其他用户发送进入聊天室欢迎语
        if conn not in conns:
            for c in conns:
                greet = '欢迎%s来到我们的聊天室!' %str(addr)
                c.send(greet.encode('utf-8'))
            conns.append(conn)
        t = threading.Thread(target=deal_conn,args=(conn,))
        t.start()
mfd_clnt.py(多用户全双工聊天客户端)
from socket import *
from select import *
import sys

HOST = 'localhost'
POST = 21568
BUFSIZE = 1024
ADDR = (HOST, POST)

with socket(AF_INET, SOCK_STREAM) as server:
    server.connect(ADDR)
    inpu = [server,sys.stdin]
    while True:
        r_list, w_list, e_list = select(inpu,[],[])
        for s in r_list:
            if s == server:
                data = server.recv(BUFSIZE)
                if not data: break
                print((data.decode('utf-8')))
            else:
                data = input('>>> ')
                if not data:break
                server.send(data.encode('utf-8'))

9. 多用户、多房间、全双工聊天
####### mmfd_server(多用户多房间全双工聊天)

from socket import *
import re
import threading

HOST = ''
PORT = 21568
BUFSIZE = 1024
ADDR = (HOST, PORT)

rooms = {}
conns = {}

REFUSE = '对方正在聊天,您的请求拒绝连接'.encode('utf-8')
WAITING = '请等待对方上线'.encode('utf-8')
INPUT_ERROR = '您的输入有误'.encode('utf-8')


def deal_conn(name):
    while True:
        conn_from = conns[name]
        data = conn_from.recv(BUFSIZE)
        if not data:break
        if rooms[name] in conns:
            conn_to = conns[rooms[name]]
            conn_to.send(data)
        else:
            conn_from.send(WAITING)

with socket(AF_INET, SOCK_STREAM) as server:
    server.bind(ADDR)
    server.listen(10)
    while True:
        conn, addr = server.accept()
        settings = conn.recv(BUFSIZE)
        patt = r'name:(.+)\sto:(.+)'
        m = re.match(patt,settings.decode('utf-8'))
        if not m:conn.send(INPUT_ERROR)
        name = m.group(1)
        if name not in conns:
            conns[name] = conn

        to = m.group(2)
        if name not in rooms and to not in rooms:
            rooms[name] = to
            rooms[to] = name
        elif name in rooms and rooms[name] != to:
            del conns[name]
            if name in rooms:
                del rooms[name]
            conn.send(REFUSE)
            conn.close()

        t = threading.Thread(target=deal_conn,args=(name,))
        t.start()
mmfd_clnt(多用户多房间全双工聊天)
from socket import *
from select import *
import sys

HOST = 'localhost'
POST = 21568
BUFSIZE = 1024
ADDR = (HOST, POST)

with socket(AF_INET, SOCK_STREAM) as server:
    server.connect(ADDR)
    inpu = [server,sys.stdin]
    print("请输入你的姓名和对方的姓名(格式name:你的姓名 to:对方姓名)")
    data = input('')
    server.send(data.encode('utf-8'))
    while True:
        r_list, w_list, e_list = select(inpu,[],[])
        for s in r_list:
            if s == server:
                data = server.recv(BUFSIZE)
                if not data: break
                print((data.decode('utf-8')))
            else:
                data = input('>>> ')
                if not data:break
                server.send(data.encode('utf-8'))
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容