zoukankan      html  css  js  c++  java
  • 基于tcp的下载文件,以及struct模块的应用。

    一 基于TCP的下载

    客户端:

    from socket import *
    import os
    def main():
        tcp_socket = socket(AF_INET, SOCK_STREAM)# 建立套接字
        tcp_ip = input("请输入ip:")
        tcp_port = int(input("请输入端口:"))# 接收用输入的服务器端的ip和端口
        tcp_socket.connect((tcp_ip, tcp_port))# 连接服务器
        file_name = input("请输入要下载的文件名:")# 输入要下载的文件名
        tcp_socket.send(file_name.encode())# 将文件名发送至服务器端
        new_file = open(file_name, "wb")# 创建一个空文件
        time = 0# 用于计算读取的字节数
        while True:
            mes = tcp_socket.recv(1024)# 接收服务器端返回的内容
            if mes:# 如果内容不为空执行
                new_file.write(mes.decode())# 解码并向文件内写入
                time += len(mes)# 计算字节
            else:
                if time == 0:# 如果字节数为空即未收到内容
                    new_file.close()# 关闭文件
                    os.remove(file_name) # 删除刚刚创建的文件
                    print("没有您要下载的文件")
                else:
                    print("文件下载成功") # 如过time有值时name文件传输完成
                break
        tcp_socket.close() # 关闭套接字
    if __name__ == '__main__':
     main()

    服务端:

    import socket
    def file_deal(file_name):# 定义函数用于处理用户索要下载的文件
        try:
            files = open(file_name, "rb") # 二进制方式读取
            mes = files.read()
        except:
            print("没有该文件")
        else:
            files.close()
            return mes
    def main():
        tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 创建套接字
        tcp_socket.bind(("",8080)) # 固定端口号
        tcp_socket.listen(128)# 将主动套接字转为被动套接字,监听连接客户端
        while True:
            client_socket,client_addr = tcp_socket.accept()# 利用accept获取分套接字以及客户端的地址
            file_name = client_socket.recv(4096)# 接收客户端的数据
            mes = file_deal(file_name)# 调用函数处理用户下载的文件
            if mes:# 如果文件不为空发送
                client_socket.send(mes)
            client_socket.close()#关闭分套接字
    if __name__ == "__main__":
        main()

     二  基于TCP的套接字通讯:

    客户端client_side:

    import socket c
    =socket.socket(socket.AF_INET,socket.SOCK_STREAM)      #套接字 c.connect(('127.0.0.1',8080))                  #connect对应server_side中的accept。 while True: try: msg=input('>:') c.send(msg.encode()) s_data=c.recv(1024) print(s_data.decode()) except Exception as e: print(e) c.close()

    服务端server_side:
    import socket

    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    s.bind(('127.0.0.1',8080))
    s.listen(5)

    while True:
    conn,addr=s.accept()#等待客户端的连接,对应client_side端的connect。
    try:
    while True:
    client_data=conn.recv(1024)
    conn.send(client_data.upper())
    print(client_data.decode())
    except Exception as e:
    print(e)
    conn.close()

    s.close()
    TCP的一个通讯过程,服务端先启动,通过导入socket模块,产生一个客户端套接字,首先我们应该绑定一个固定的ip与端口port,那么客户端再访问就不需要每次都去找
    服务端。那么套接字下面的listen()功能,主要是限制同时请求数,也就是listen控制的是
    同时请求数,而不是连接数,连接数是跟服务器的性能相关的,
    同时请求数,而不是连接数,连接数是跟服务器的性能相关的,性能越好能建的连接数也越多,这些都准备好之后就是等待客户端的连接请求,我们这里然后再accept()
    这里等待客户端连接进来,那么accept()其实就对应于客户端的connect(),那么一旦连接建成,就准备进行数据的传输,我们客户端首先发一个数据请求,其实客户端的
    数据首先是send()到客户端的一个操作系统的缓存中,因为应用软件是没办法直接操作网卡进行数据的传输,所以他要借助操作系统来调用网卡,进行数据的传输,
    那么再send()数据的时候我们pycharm会有一个优化的机制nagle,就是对于数据量小且发送间隔短的数据会一起发送给服务端,这是造成粘包的一种情况。那么我们在接收
    的时候同样是从操作系统的缓存中取数据,那么每次如果最大值是recv(1024)的话,就会造成可能一次没办法取出来全部的发送过来的数据,同样造成粘包。

    三 基于UDP的套接字通讯:

    server_side
    import socket s
    =socket.socket(socket.AF_INET,socket.SOCK_DGRAM) s.bind(('127.0.0.1',8080)) while True: data,addr=s.recvfrom(1024) s.sendto(data.upper(),addr) print(data,addr) s.close()

    client_side:
    import socket
    c=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

    while True:

    c.sendto(b'hello',('127.0.0.1',8080))
    c.sendto(b'world',('127.0.0.1',8080))
    c.sendto(b'python',('127.0.0.1',8080))
    data,addr=c.recvfrom(1024)
    print(data.decode(),addr)
    c.close()
     
  • 相关阅读:
    全局变量与全局静态变量的区别:
    Python模块学习 ---- datetime
    python sys.path用法
    过来人谈《去360还是留在百度?》
    [编码问题] Python错误: SyntaxError: Non-ASCII character
    E513: write error, conversion failed (make 'fenc' empty to override)"解决办法
    巴真的点评
    set之hashset与TreeSet、LinkedHashSet实现原理
    list之linedlist与arraylist实现原理
    统一会话与单点登录
  • 原文地址:https://www.cnblogs.com/zhangsanfeng/p/8976974.html
Copyright © 2011-2022 走看看