• HNU计网实验:实验二 网络基础编程实验(JAVA\Python3)


    说些什么

    记得当时做实验的时候我是满心的卧槽的,因为实验一和实验二简直是天壤之别,我记得在验收前的那个下午,我依然在疯狂改代码。

    众所周知,我是一个衷心于摸鱼的小菜鸡,所以我这个代码其实是我在别人代码的基础上改出来的一个,其实理论上我应该bia出来参考的博客的网址的,但是这是好早之前的了我找不到了…

    实验目的

    通过本实验,学习采用Socket(套接字)设计简单的网络数据收发程序,理解应用数据包是如何通过传输层进行传送的。

    实验内容

    Socket(套接字)是一种抽象层,应用程序通过它来发送和接收数据,就像应用程序打开一个文件句柄,将数据读写到稳定的存储器上一样。一个socket允许应用程序添加到网络中,并与处于同一个网络中的其他应用程序进行通信。一台计算机上的应用程序向socket写入的信息能够被另一台计算机上的另一个应用程序读取,反之亦然。
    不同类型的socket与不同类型的底层协议族以及同一协议族中的不同协议栈相关联。现在TCP/IP协议族中的主要socket类型为流套接字(sockets sockets)和数据报套接字(datagram sockets)。流套接字将TCP作为其端对端协议(底层使用IP协议),提供了一个可信赖的字节流服务。一个TCP/IP流套接字代表了TCP连接的一端。数据报套接字使用UDP协议(底层同样使用IP协议),提供了一个"尽力而为"(best-effort)的数据报服务,应用程序可以通过它发送最长65500字节的个人信息。一个TCP/IP套接字由一个互联网地址,一个端对端协议(TCP或UDP协议)以及一个端口号唯一确定。

    写一个简单的chat程序,并能互传文件,编程语言不限

    客户端

    #客户端的chat
    
    import socket
    import sys
    import os
    
    ip_port = ('127.0.0.1',9998) #使用9999会提示被占用?
    sk = socket.socket()
    sk.connect(ip_port)
    container = {'key':'','data':''} #文件路径的剪切
    while True:
        FLAG = input('0.接收文件 1.发送文件 2.进行消息发送\n')
        sk.sendall(str(FLAG).encode('utf-8'))
    
        if FLAG=='1': #发送文件,即原本的功能
            path = input('path:') # 客户端输入要上传文件的路径 
            path = 'F:\\\\'+path #F盘的test10031.txt
            print('哈哈哈哈哈',path) ##################test
            file_name = os.path.basename(path) # 根据路径获取文件名
            file_size=os.stat(path).st_size # 获取文件大小
            Informf=(file_name+'|'+str(file_size)) #客户端的打包
            sk.send(Informf.encode()) # 发送文件名 和 文件大小
            # 为了防止粘包,将文件名和大小发送过去之后,等待服务端收到,直到从服务端接受一个信号(说明服务端已经收到)
            msg=sk.recv(1024)
            print(msg.decode())
    
            send_size = 0
            f= open(path,'rb')
            Flag = True
            while Flag:
                if send_size + 1024 >file_size:
                    data = f.read(file_size-send_size)
                    Flag = False
                else:
                    data = f.read(1024)
                    send_size+=1024
                sk.send(data)
    
            aaa = sk.recv(1024) #新增接收
            print(aaa.decode())
    
            f.close()
    
        elif FLAG=='0' : #接收
            message=sk.recv(1024)
            print(message.decode(encoding='utf8'))
    
            message = input('path: ')
            message = str(message)
            # 发送数据 加码
            sk.sendall(message.encode('utf-8'))
            print('客户端等待...')
    
            #之前的Srv
            pre_data = sk.recv(1024).decode()
            #获取请求方法、文件名、文件大小
            file_name,file_size = pre_data.split('|') #服务器的解包
            # 防止粘包,给客户端发送一个信号。
            sk.sendall('收到'.encode())            
            #已经接收文件的大小
            recv_size = 0
            file_dir = os.path.join('F:\\\\',message) #下载文件路径拼接 ####理论上没错的样子
            print('嘿嘿嘿嘿嘿',file_dir)
            f = open(file_dir,'wb')
            Flag = True
            while Flag:
                #未上传完毕,
                if int(file_size)>recv_size:
                    #最多接收1024,可能接收的小于1024
                    data = sk.recv(1024) 
                    recv_size+=len(data)
                    #写入文件
                    f.write(data)
                #上传完毕,则退出循环
                else:
                    recv_size = 0
                    Flag = False
    
            sk.sendall('下载完成'.encode()) #新增发送
                    
            print('接收成功')
            f.close()
            #Srv至此
    
        else : #进行信息发送
            print('开始进行聊天')
    
            while True:
                msg = input("> ")
                if msg == 'stop':
                    sk.send('stop'.encode('utf-8')) #客户端发送停止消息
                    break
                elif not msg:
                    continue
                sk.send(msg.encode('utf-8'))  # 客户端发送消息
    
                rev_data = sk.recv(1024)  # 客户端接受消息
                if not rev_data:
                    break
    
                print('服务器消息:', rev_data.decode('utf-8'))
    
    
    sk.close()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104

    服务端

    #服务端
    import socketserver
    import os
    
    class MyServer(socketserver.BaseRequestHandler):
        def handle(self):
            conn = self.request
            print ('connected...')
            while True:
    
                order = conn.recv(1024).decode(encoding='utf8') #增加读取
                print('执行',order)
    
                if order == '1' : #接收文件,即原本的任务
    
                    print('服务器等待...')
    
                    pre_data = conn.recv(1024).decode()
                    #获取请求方法、文件名、文件大小
                    file_name,file_size = pre_data.split('|') #服务器的解包
                    # 防止粘包,给客户端发送一个信号。
                    conn.sendall('收到'.encode())            
                    #已经接收文件的大小
                    recv_size = 0
                    file_dir = os.path.join('D:\\\\',file_name) #接收的文件路径拼接 #现在没错了
    
                    print("啦啦啦啦啦",file_dir) #####test
    
                    f = open(file_dir,'wb')
                    Flag = True
                    while Flag:
                        #未上传完毕,
                        if int(file_size)>recv_size:
                           #最多接收1024,可能接收的小于1024
                            data = conn.recv(1024) 
                            recv_size+=len(data)
                            #写入文件
                            f.write(data)
                        #上传完毕,则退出循环
                        else:
                            recv_size = 0
                            Flag = False
    
                    conn.sendall('下载完成'.encode()) #添加发送
    
                    print('上传成功')
                    f.close()
            
                if order == '0' : #发送文件
                    conn.sendall('服务器准备发送文件'.encode('utf-8'))
    
                    #原来的Clt
                    #path = input('path:') # 客户端输入要上传文件的路径
                    path = conn.recv(1024).decode() #这里路径是从客户端读取的
                    #file_name = os.path.basename(path) # 根据路径获取文件名
                    file_name = os.path.join('D:\\\\', path) #拼接 ###########理论上没错
                    print('耶耶耶耶耶',file_name)
                    file_size=os.stat(file_name).st_size # 获取文件大小
                    Informf=(file_name+'|'+str(file_size)) # 包装文件名 和 文件大小
                    conn.send(Informf.encode()) # 发送
                    # 为了防止粘包,将文件名和大小发送过去之后,等待服务端收到,直到从服务端接受一个信号(说明服务端已经收到)
                    bbb=conn.recv(1024).decode()
                    print(bbb)
    
                    send_size = 0
                    f= open(file_name,'rb')
                    Flag = True
                    while Flag:
                        if send_size + 1024 >file_size:
                            data = f.read(file_size-send_size)
                            Flag = False
                        else:
                            data = f.read(1024)
                            send_size+=1024
                        conn.send(data)
    
                    conn.recv(1024) #新增接收
                    f.close()
    
                if order == '2' :
                    print('开始进行聊天')
                    while True:
                        data = conn.recv(1024)  # 接受客户端发送的消息
                        print('客户端消息:', data.decode('utf-8'))
                        if not data:
                            continue
                        elif data.decode() == 'stop':
                            print('停止聊天')
                            break
                        message = input('> ')
    
                        conn.send(message.encode('utf-8'))  # 客户端发送消息
        
    instance = socketserver.ThreadingTCPServer(('127.0.0.1',9998),MyServer)
    instance.serve_forever()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95

    主要思路就是通过FLAG的值来判断操作:
    FLAG=='1’的时候就是发送文件
    FLAG=='0’的时候就是接收文件
    FLAG=='2’的时候就是信息互发

    有些奇奇怪怪的输出不需要在意,当时有bug然后de不出来,就想着通过输出来看在哪一步执行不来…
    朴素的程序员往往用最质朴的方法来debug…
    我真的会谢…

  • 相关阅读:
    Matlab之多平台雷达检测融合仿真(附源码)
    程序员积累的编程知识十年后有多少变得没用?
    【进阶篇】Java 实际开发中积累的几个小技巧(二)
    这个字典库引起了 Python 之父的注意!你用过吗?
    Element+Vue+OpenLayers的项目实战
    Win10自带输入法怎么删除-Win10卸载微软输入法的方法
    前端项目如何找到所有未被引用的文件
    Pytorch lr_scheduler.LambdaLR()的简单理解与用法
    专题一matlab基础知识
    Hiredis的基本使用
  • 原文地址:https://blog.csdn.net/qq_45795586/article/details/125451699