通过套接字发送文件时出现问题 [英] Problems while sending file through socket

查看:80
本文介绍了通过套接字发送文件时出现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个服务器客户端应用程序,其中服务器将文件发送到客户端.
但是,一旦发送了文件,连接就会关闭,并且我无法第二次发送文件.我必须重新启动两个(服务器/客户端)应用程序才能发送文件.整个连接断开后,我只能在1次运行中发送1个文件.
我的Server(Sender)代码:

I have created a server client application in which server sends a file to the client.
But as soon as the file is sent the connection is closed and I am not able to send the file for the second time. I have to restart both (server/client) applications to send the file.I can send only 1 file in 1 run after that the entire connection is lost.
My code for Server(Sender):

''#sends filename, filelength, filebytes
Dim info As New IO.FileInfo("C:\Pritam.bin")
''#writes a String and a Long with binarywriter (wrapping networkstream)
Dim bw As New IO.BinaryWriter(clientSocket.GetStream)
bw.Write(info.Name)
bw.Write(info.Length)
''#using filestream to read file, writes this directly to networkstream
Using fs As New IO.FileStream("C:\Pritam.bin", IO.FileMode.Open, IO.FileAccess.Read)
    Dim buffer(8092) As Byte, reads As Integer = -1
    Do Until reads = 0
        reads = fs.Read(buffer, 0, buffer.Length)
        clientSocket.GetStream.Write(buffer, 0, reads)
    Loop
End Using
bw.Close()



我的客户(接收方):



My client(Receiver):

Dim filename, filepath As String, filelen As Long
        ''#using binaryreader (wrapped networkstream) to read a String and a Long
       Dim br As New IO.BinaryReader(clientSocket.GetStream)
       filename = br.ReadString
       filelen = br.ReadInt64
        ''#filepath = IO.Path.Combine(Application.StartupPath, filename)
       filepath = IO.Path.Combine("H:\", filename)
       Dim buffer(8092) As Byte, readstotal As Long = 0
       Dim reads As Integer = -1
        ''#using filestream to write read filebytes directly from networkstream
       Using fs As New IO.FileStream(filepath, IO.FileMode.Create, IO.FileAccess.Write)
           Do Until readstotal = filelen
               reads = clientSocket.GetStream.Read(buffer, 0, buffer.Length)
               fs.Write(buffer, 0, reads)
               readstotal += reads
           Loop
       End Using
       MsgBox("received: " & filename)
       br.Close()



谢谢您.



Thank you

推荐答案

您可以通过在服务器端和System.Net.Sockets.TcpClient上使用System.Net.Sockets.TcpListener类来大大简化任务并使它更可靠.通常,您需要在服务器端创建两个线程:一个线程侦听并接受新连接,另一个线程在循环中与每个客户端执行交换协议.这样,您的服务器将能够同时与多个客户端一起工作.这两个线程应支持代表远程套接字的客户端共享容器,使用此容器(通过侦听线程进行写入,通过读/写线程进行读取)应受到锁的保护,但最好由System.Threading.ReaderWriterLockSlim保护.

当客户端连接并需要上载文件时,它应该发送一些请求信息,并且服务器应以预下载状态做出响应,包括文件的预期大小.您可能需要在一个会话中下载多个文件;在这种情况下,应将具有数字和名称(或用于文件识别的任何其他信息)的某种结构发送到服务器,并且服务器应使用包含文件可用性信息和每个文件的预期大小的另一种结构进行响应.这应该是交换应用程序级协议的一部分.下一阶段将是下载过程本身.在完全传输数据或发生错误之前,会话不会在任何一方关闭.该协议应包含带有错误信息的数据.如果成功下载,会话应在客户端关闭.这是因为只有客户端才拥有有关文件长度的所有信息,并且只有在接收到最后一个字节,将其写入文件和磁盘以及关闭接收到的文件时,才可以触发关闭会话.在这种情况下,实际上并不需要断开连接.

—SA
You could greatly simplify the task and make it robust by using System.Net.Sockets.TcpListener class on server side and System.Net.Sockets.TcpClient. You generally need to create two threads on the server side: one listens and accept new connections, another one performs exchange protocol with each client in a loop. In this way, your server will be able to work with several clients at the same time. These two threads should support a shared container of clients representing remote sockets, working with this container (writing by listening thread, reading by read/write thread) should be protected by a lock, but better by a System.Threading.ReaderWriterLockSlim.

When the client is connected and needs to upload a file, it should send some request information, and the server should respond with pre-download status including expected size of the file. You may want to download several files in one session; in this case some structure with the numbers and names (or any other information for file identification) should be send to the server, and the server should respond with another structure containing file availability information and the expected size of each file). This should be a part of exchange application-level protocol. Next phase will be downloading process itself. The session will not be closed on either side until the data is fully transmitted or error occurs. The protocol should include a data with error information. The session should be closed on client side in case of successful download. This is because only the client has all the information on the length(s) of the file(s) and can trigger closing the session only when last byte is received, written to the file and disk and received files are closed. No graceful disconnection is really needed in this case.

—SA


这篇关于通过套接字发送文件时出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆