Python 网络编程 - 04 tcp客户端/tcp服务器/文件下载器

😝😝

目录
一、tcp客户端构建流程
二、tcp服务器端构建流程
三、案例——文件下载器
四、tcp注意点

一、tcp客户端构建流程

  • 1、创建tcp套接字
  • 2、链接服务器
  • 3、发送/接收数据
  • 4、关闭套接字
import socket

def main():

    # 1. 创建tcp套接字  SOCK_DGRAM:udp  tcp:SOCK_STREAM
    tcp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

    # 2. 链接服务器
    tcp_socket.connect(("192.168.140.154",7799))
    # 3. 发送/接收数据
    send_data = input("请输入要发送的数据:")
    tcp_socket.send(send_data.encode("utf-8"))
    # 4. 关闭套接字
    tcp_socket.close()

if __name__ == '__main__':
    main()

由于已经安装了sokit,现在只需要在终端直接输入sokit则便会启动,之后输入相应的ip以及Port即可

图片.png

二、tcp服务器端构建流程

  • 1、创建套接字
  • 2、绑定ip还 Port
  • 3、lisen使用套接字变成被动链接 (让默认的套接字由主动变被动)
  • 4、accept等待客服端连接
  • 5、recv/send接收放发送数据
  • 6、关闭套接字
import socket

def main():
    # 1. socket创建一个套接字
    utp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

    # 2. bind绑定ip和port
    utp_socket.bind(("",8855))

    # 3.listen使套接字变为可以被动链接
    utp_socket.listen(128)

    print("--------1----------")
    # 4. accept等待客户端的链接
    # 返回值是一个元祖
    # 拆包  例如:(a,b) = (1,2)     
    # 如果有新的客户端来链接服务器,那么就产生一个新的套接字专门为这个客户端服务
    # client_socket用来为这个客户端服务
    # tcp_server_socket就可以省下来专门等待其他新客户端的链接
    client_socket,clientAddr = utp_socket.accept()

    print("--------2----------")
    print(clientAddr)

    # 5.recv / send接收发送数据
    #  接收客服端发送过来的请求
    recv_data = client_socket.recv(1024)  # 接收1024个字节
    print('接收到的数据为: %s' % recv_data)

    # 回送一部分数据给客服端
    client_socket.send("-------ok-------".encode("utf-8"))

    # 6. 关闭套接字
    client_socket.close()
    utp_socket.close()
if __name__ == '__main__':
    main()


图片.png

tcp服务器循环为多个客户端服务

import socket

def main():
    # 1. socket创建一个套接字
    utp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    # 2. bind绑定ip和port
    utp_socket.bind(("",8822))
    # 3.listen使套接字变为可以被动链接
    utp_socket.listen(128)
    print("--------1----------")
    # 第一个while循环的目的:为多个客户端服务
    while True:
        print("等待一个新的客户端的到来")
        # 4. accept等待客户端的链接
        # 返回值是一个元祖
        # 拆包  例如:(a,b) = (1,2)
        # 如果有新的客户端来链接服务器,那么就产生一个新的套接字专门为这个客户端服务
        # client_socket用来为这个客户端服务
        # tcp_server_socket就可以省下来专门等待其他新客户端的链接
        client_socket,clientAddr = utp_socket.accept()
        print("一个新的客户端已经到来%s" % str(clientAddr))
        print(clientAddr)

        # 第二个while循环的目的:为同一个客户端 服务多次
        while True:
            # recv / send接收发送数据
            # 5. 接收客服端发送过来的请求
            recv_data = client_socket.recv(1024)  # 接收1024个字节
            print('接收到的数据为: %s' % recv_data)

            # 如果recv解堵塞,那么有2种方式:
            # 1、客户端发送过来数据
            # 2、客户端调用 close 导致了 这里 recv 堵塞
            if recv_data:

                # 回送一部分数据给客服端
                client_socket.send("-------ok-------".encode("utf-8"))
            else:
                print("客户端关闭了自己的套接字或则断开了链接")
                break
        # 6. 关闭套接字,关闭accept 返回的套接字 意味着 不会在为这个客户端服务
        client_socket.close()

    # 如果将监听套接字 关闭了,那么会导致 不能再次等待新客户端的到来,也就是 套接字.accept()会失败
    utp_socket.close()

if __name__ == '__main__':
    main()

图片.png

三、案例——文件下载器

服务器代码如下:

import socket

def main():
    # 1.创建socket
    tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    # 2.绑定本地信息
    tcp_server_socket.bind(("192.168.140.148",7800))
    # 3.将主动套接字变为被动套接字
    tcp_server_socket.listen(128)

    while True:

        print("等待客户端的连接")
        # 4.等待客户端的连接
        new_tcp_socket,client_addr = tcp_server_socket.accept()
        # 5.接收对方发送过来的数据
        recv_data = new_tcp_socket.recv(1024)
        file_name = recv_data.decode("utf-8")
        print("对方请求下载的文件名为:%s" % file_name)
        # 6.处理客户端的内容
        file_content = get_file_content(file_name)

        # 发送文件的数据给客户端
        # 因为获取打开文件时是以rb方式打开,所以file_content中的数据已经是二进制的格式,因此不需要encode编码
        if file_content:
            new_tcp_socket.send(file_content)
        # 6.关闭为这个客户端服务的套接字
        new_tcp_socket.close()
    # 7.关闭监听服务器套接字
    tcp_server_socket.close()

def get_file_content(file_name):
    """获取文件的内容"""
    try:
        with open(file_name, "rb") as f:
            content = f.read()
        return content
    except:
        print("没有下载的文件:%s" % file_name)


if __name__ == '__main__':

    main()
图片.png

客户端代码如下:

import socket


# 客户端代码
def main():

    # 1.创建socket
    tcp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    # 2.链接服务器
    tcp_socket.connect(("192.168.140.148",8890))
    # 3.获取下载的文件名字
    download_file_name = input("请输入要下载的文件名字:")
    # 4.将文件文字发送到服务器
    tcp_socket.send(download_file_name.encode("utf-8"))

    # 5.接收文件中的数据
    recv_data = tcp_socket.recv(1024) # 1024 ----->1K  1024 * 1024 ----->1k *1024 = 1M 1024 * 1024 * 1024 ----->1G

    # 6.保存接收到的数据到一个文件中
    if recv_data:
        with open("[新]" + download_file_name, "wb") as file:
            file.write(recv_data)

    # 7.关闭套接字
    tcp_socket.close()

if __name__ == '__main__':

    main()

四、tcp注意点

1、tcp服务器一般情况下都需要绑定,否则客户端找不到这个服务器
2、tcp客户端一般不绑定,因为是主动链接服务器,所以只要确定好服务器的ip、port等信息就好,本地客户端可以随机
3、tcp服务器中通过listen可以将socket创建出来的主动套接字变为被动的,这是做tcp服务器时必须要做的
4、当客户端需要链接服务器时,就需要使用connect进行链接,udp是不需要链接的而是直接发送,但是tcp必须先链接,只有链接成功才能通信
5、当一个tcp客户端连接服务器时,服务器端会有1个新的套接字,这个套接字用来标记这个客户端,单独为这个客户端服务
6、listen后的套接字是被动套接字,用来接收新的客户端的链接请求的,而accept返回的新套接字是标记这个新客户端的
7、关闭listen后的套接字意味着被动套接字关闭了,会导致新的客户端不能够链接服务器,但是之前已经链接成功的客户端正常通信。
8、关闭accept返回的套接字意味着这个客户端已经服务完毕
9、当客户端的套接字调用close后,服务器端会recv解堵塞,并且返回的长度为0,因此服务器可以通过返回数据的长度来区别客户端是否已经下线

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260

推荐阅读更多精彩内容