跟着项目做,但是问题有点多,关于网络编程,还没有看,给自己挖个坑,等哔哩哔哩看了再说

    这是一个关于tcp传输文件的一个脚本 。
    其中问题不少,虽然我解决了不少,但是还有点,留着,等看一遍网络编程,再来看一遍,估计就没什么问题了.
    client.py

    1. from socket import *
    2. import os
    3. import sys
    4. import json
    5. import struct
    6. from optparse import OptionParser
    7. def recv_file(head_dir,tcp_client)
    8. filename = head_dir['filename']
    9. filesize = head_dir['filesize']
    10. print('[+]filename'+filename[0])
    11. print('[+]filesize' +str(filesize[0]))
    12. recv_len = 0
    13. f = open(filename[0],'wb')
    14. while recv_len<filesize:
    15. if(filesize>1024):
    16. recv_mesg = tcp_client.recv(filesize)
    17. recv_mesg + = len(recv_mesg)
    18. f.write(recv_mesg)
    19. else:
    20. recv_mesg = tcp_client.recv(filesize)
    21. recv_mesg + =len(recv_mesg)
    22. f.write(recv_mesg)
    23. f.close()
    24. print("[+]文件传输完毕")
    25. def main():
    26. parser = OptionParser("Usage:%prog -u <traget address> -p <port>") #输出帮助信息
    27. parser.add_option('-u', type='string', dest='ip', help='specify traget ip') # 获取目标ip
    28. parser.add_option('-p', type='string', dest='port', help='specify traget port') # 获取目标端口
    29. options, args = parser.parse_args()
    30. traget_ip = options.ip
    31. traget_port = int(options.port)
    32. # print(traget_ip,traget_port)
    33. tcp_client= socket(AF_INET, SOCK_STREAM) #socket 初始化 不要将文件名和socket相同
    34. ip_port = ((traget_ip, traget_port))
    35. print("[+]正在尝试链接")
    36. tcp_client.connect(ip_port) # connect_ex 和 connect差不多
    37. print("[+]等待服务端应答")
    38. struct_len=tcp_client.recv(4) #定义接受长度
    39. struct_info_len = struct.unpack('i',struct_len)[0] #解析得到报头信息长度
    40. print("[+]接受报头长度为:"+ str(struct_info_len) )
    41. head_info=tcp_client.recv(struct_info_len)
    42. head_dir = json.loads(head_info.decode('utf-8')) # 将报头反序列化
    43. print("[+]报头内容为:"+str(head_dir) )
    44. recv_file(head_dir,tcp_client)
    45. if __name__=='__main__':
    46. try:
    47. main()
    48. except keyboardInterrupt:
    49. print("interrupted by user,killing all threads..")

    server.py

    1. import socketserver
    2. import struct
    3. import os
    4. import re
    5. import json
    6. import struct
    7. from optparse import OptionParser
    8. def SendFile(conn, head_info,head_info_len,filename): #发送文件
    9. try:
    10. conn.send(head_info_len) # send 发送
    11. conn.send(head_info.encoding('utf-8'))
    12. with open(filename,'rb') as f:
    13. conn.sendall(f.read()) # sendall 发送所有读出的文件
    14. print('[+]send success!'+filename)
    15. except:
    16. print('send failes' + filename)
    17. def operafile(filename): #返回文件名和文件大小
    18. filesize = os.path.getsize(filename)
    19. pattern = re.compile(r'([^<>/\\\|:""\*\?]+\.\w+$)')
    20. data = pattern.findall(filename)
    21. head_dir ={
    22. 'filename': data ,
    23. 'filesize': filesize
    24. }
    25. head_info = json.dump(head_dir) # 将数据结构更改为json格式
    26. head_info_len = struct.pack('i',len(head_info)) # 将数据转换为字节流 格式符”i”表示转换为int,’ii’表示有两个int变量
    27. return head_info,head_info_len
    28. class MyServer(socketserver.BaseRequestHandler):
    29. buffsize = 1024
    30. def handle(self):
    31. print('[+]远程客户机ip',self.client_address[0],'\n')
    32. while True: #使用循环是为了让多个客户端连接一个服务端
    33. filename = input('请输入需要传输的文件地址>>>').strip() #strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列
    34. if(filename == 'exit'):
    35. break
    36. head_info,head_info_len = operafile(filename)
    37. sendFile(self.request,head_info,head_info_len,filename)
    38. self.request.close()
    39. def main():
    40. parser=OptionParser("Usage:prog -p <port>")
    41. parser.add_option('-p', type='string', dest='port', help='specify targer port' ) #获取监听端口
    42. options , args =parser.parse_args()
    43. port = int(options.port) #需要指定为int,不然会报错
    44. print('[+]正在监听'+str(port))
    45. s = socketserver.ThreadingTCPServer(('0.0.0.0', port), MyServer)
    46. #ThreadingTCPServer,就是线程化的TCP服务器,客户端发起的TCP连接,在服务器侧,都是一个个的线程。显然,这个ThreadingTCPServer是异步多线程的框架模型
    47. s.serve_forever()
    48. if __name__ == "__main__":
    49. try:
    50. main()
    51. except KeyboardInterrupt:
    52. print("interrupted by user, killing all threads...")