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'))

转载于:https://my.oschina.net/u/3579120/blog/1507556

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值