python用tcp写server传输文件遇到的问题

我被要求写包括client,和server在内的三个文件来在本地实现文件传输(通过cmd),
但是我的另一个文件(我取名为Others.py)和client.py好像有问题:
代码如下

# server.py
import socket
import sys
import Others

# Create socket, AF_INET corresponds to IPv4, and SOCK_STREAM corresponds to TCP
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# bind to the port
tcp_socket.bind(('', int(sys.argv[1])))

# Convert active socket to passive socket
tcp_socket.listen(5)
print("Server is listening:")
# The combination of an IPv4 address and a port number is known as the socket number
# A pair of sockets, one socket at the client side and other socket at the server side,
# define the TCP/UDP connection end points
# A socket number can uniquely identify a network resource in the whole internet.
# From https://www.omnisecu.com/tcpip/what-are-port-and-socket-numbers.php

while True:
    # Use accept to get the address of the sub-socket and the client
    client_socket, address = tcp_socket.accept()

    print(f"connection from {address}has been established")

    # send message
    client_socket.send(bytes(f"Welcome to this server!", "utf-8"))
    Others.recv_file(client_socket, 'my.txt')
    client_socket.close()
# client.py
import socket
import sys
import Others

#def main():
# Create socket
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      
ip = sys.argv[1]
# The port for my laptop
port = int(sys.argv[2])

# connect to the server
tcp_socket.connect((ip, port))
full_msg = ''

filename = input("please type in your file name \n")
tcp_socket.send(bytes(filename,'utf-8'))

while True:
    print('receiving...')

    # Receive the content returned by the server
    msg = tcp_socket.recv(4)

    if msg:
        break
    full_msg += msg.decode("utf-8")

print(full_msg)

Others.send_file(tcp_socket, "C:/Users/ASUS/Desktop/123.txt")

tcp_socket.close()
print('connection closed')
# Others.py
def send_file(socket , filename):
    name = filename

    socket.send(bytes(f"{name}", 'utf-8'))
    # read in binary mode
    file = open(filename, 'rb')
    socket.send(file)


def recv_file(socket, filename):
    name = filename
    # write in binary mode
    file = open(name, 'wb')
    s = socket.recv(1024)
    while s:
        file.write(s)
        s = socket.recv(1024)
    file.close()

报错如下

#这是cmd的提示
Traceback (most recent call last):
  File "C:\Users\ASUS\Desktop\myTCPserver\client.py", line 33, in <module>
    Others.send_file(tcp_socket, "C:/Users/ASUS/Desktop/123.txt")
  File "C:\Users\ASUS\Desktop\myTCPserver\Others.py", line 64, in send_file
    socket.send(file)
TypeError: a bytes-like object is required, not '_io.BufferedReader'

C:\Users\ASUS\Desktop\myTCPserver>

#这是cmd的提示
C:\Users\ASUS\Desktop\myTCPserver>python server.py 6789
Server is listening:
connection from ('127.0.0.1', 55603)has been established
Traceback (most recent call last):
  File "C:\Users\ASUS\Desktop\myTCPserver\server.py", line 28, in <module>
    Others.recv_file(client_socket, 'my.txt')
  File "C:\Users\ASUS\Desktop\myTCPserver\Others.py", line 74, in recv_file
    s = socket.recv(1024)
ConnectionResetError: [WinError 10054] 远程主机强迫关闭了一个现有的连接。

C:\Users\ASUS\Desktop\myTCPserver>

不知道怎么改,不改变大概结构。有没有人看看

错误的确不少,已经都给你改过来了,也运行成功了,请采纳

客户端



# server.py
import socket
import sys
import Others
# Create socket, AF_INET corresponds to IPv4, and SOCK_STREAM corresponds to TCP
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# bind to the port
tcp_socket.bind(('', int(sys.argv[1])))
# Convert active socket to passive socket
tcp_socket.listen(5)
print("Server is listening:")
# The combination of an IPv4 address and a port number is known as the socket number
# A pair of sockets, one socket at the client side and other socket at the server side,
# define the TCP/UDP connection end points
# A socket number can uniquely identify a network resource in the whole internet.
# From https://www.omnisecu.com/tcpip/what-are-port-and-socket-numbers.php
while True:
    # Use accept to get the address of the sub-socket and the client
    client_socket, address = tcp_socket.accept()
    print(f"connection from {address}has been established")
    # send message
    client_socket.send(bytes(f"Welcome to this server!", "utf-8"))
    Others.recv_file(client_socket, 'my.txt')
    client_socket.close()

服务器

# client.py
import socket
import sys
import Others
#def main():
# Create socket
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ip =sys.argv[1]
# The port for my laptop
port =int(sys.argv[2])
# connect to the server
tcp_socket.connect((ip, port))
msg = tcp_socket.recv(1024)
print(msg.decode('utf-8'))
filename = input("please type in your file name \n")
tcp_socket.send(bytes(filename,'utf-8'))
Others.send_file(tcp_socket,filename)
tcp_socket.close()
print('connection closed')


Others.py

# Others.py
def send_file(socket , filename):
    name = filename
    socket.send(bytes(f"{name}", 'utf-8'))
    #socket.send(codes)
    # read in binary mode
    file = open(filename, 'rb').read()
    socket.send(file)
 
def recv_file(socket, filename):
    name = filename
    # write in binary mode
    file = open(name, 'wb')
    s = socket.recv(1024)
    while s:
        file.write(s)
        s = socket.recv(1024)
    file.close()


你这程序每个细节都有毛病,整个乱七八糟。
1.server在建立侦听之后,接到一个请求时要单独给它开个线程,不要直接在主线程里接收数据,否则你server一次只能服务一个client,其它客户端都会被阻塞
2.既然你client在连接后把要传输的文件名发给服务端,你服务端为什么不接收?
3.既然你知道收文件的时候得慢慢收,一点一点存,为什么发文件的时候整个文件读进内存里然后整个发出去,你不怕内存爆炸?
4.你写文件的时候模式是wb,每次执行写入都会把文件从头到尾覆盖。你应该使用a+
5.你解决了循环读文件循环发送的问题,你第一个报错自然就没了。第一个报错信息说send函数接收的数据类型错误。
6.你第二个报错问题其实跟3差不多,你的包太大,导致交换机自动把它拆成多个包,你只收了第一个包就直接close掉了,close应该是发送端close,接收端不要随便close。你的服务端就应该循环接收写入,而不要期待一下把数据收完。
总之你发送和接收应该是对应的过程,不一致肯定不对呀。


 # read in binary mode
    file = open(filename, 'rb')
    socket.send(file)

# 这里改成
file = open(filename, 'rb')
data = file.read()
socket.send(data)

如果觉得答案对你有帮助,请点击下采纳,谢谢~