C# 在TCP发送期间,断点会影响结果
我正在编写的客户机/服务器应用程序有问题。它的目的是在客户端发送特定目录的文件,并将它们发送到服务器上的目录 我用foreach获取文件,但当我在foreach的开始处设置断点,然后继续发送所有文件,直到我想在服务器中发送所有文件为止。当我删除断点并重新运行应用程序时,服务器只接收部分文件,我不知道为什么 我不确定,但我想这是一个线程问题,但不知道如何解决它 服务器:C# 在TCP发送期间,断点会影响结果,c#,tcp,sendfile,C#,Tcp,Sendfile,我正在编写的客户机/服务器应用程序有问题。它的目的是在客户端发送特定目录的文件,并将它们发送到服务器上的目录 我用foreach获取文件,但当我在foreach的开始处设置断点,然后继续发送所有文件,直到我想在服务器中发送所有文件为止。当我删除断点并重新运行应用程序时,服务器只接收部分文件,我不知道为什么 我不确定,但我想这是一个线程问题,但不知道如何解决它 服务器: static void Main(string[] args) { try {
static void Main(string[] args)
{
try
{
TcpListener listen = new TcpListener(3003);
TcpClient client;
int bufferSize = 1024;
NetworkStream netStream = null;
int bytesRead = 0;
int allBytesRead = 0;
// Start listening
listen.Start();
// Accept client
client = listen.AcceptTcpClient();
StreamReader reader = new StreamReader(client.GetStream());
netStream = client.GetStream();
string fileName;
bool endOfSend=false;
do
{
fileName = reader.ReadLine();
// Read length of incoming data
byte[] length = new byte[4];
bytesRead = netStream.Read(length, 0, 4);
int dataLength = BitConverter.ToInt32(length, 0);
// Read the data
int bytesLeft = dataLength;
byte[] data = new byte[dataLength];
while (bytesLeft > 0)
{
int nextPacketSize = (bytesLeft > bufferSize) ? bufferSize : bytesLeft;
bytesRead = netStream.Read(data, allBytesRead, nextPacketSize);
allBytesRead += bytesRead;
bytesLeft -= bytesRead;
}
allBytesRead = 0;
bytesLeft = 0;
bytesRead = 0;
// Save file to desktop
Console.WriteLine("File {0} received.", fileName);
File.WriteAllBytes(@"C:\Users\toto2\Desktop\" + fileName, data);
} while (!endOfSend);
netStream.Close();
client.Close();
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine("File Receiving fail." + ex.Message);
}
}
客户:
static void Main(string[] args)
{
try
{
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
int port = 3003;
TcpClient client = new TcpClient();
//NetworkStream netStream;
// Connect to server
try
{
client.Connect(new IPEndPoint(ipAddress, port));
Console.WriteLine("Connecté.....");
SendFiles(client);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
// Clean up
client.Close();
Console.Read();
}
catch (Exception ex)
{
Console.WriteLine("File Sending fail." + ex.Message);
}
}
public static void SendFiles(TcpClient cli) {
NetworkStream netS=cli.GetStream();
int bufferSize = 1024;
string[] files = Directory.GetFiles(@"C:\Users\toto\Mes Images\test");
StreamWriter writer = new StreamWriter(cli.GetStream());
foreach (string item in files)
{
writer.WriteLine(Path.GetFileName(item));
writer.Flush();
// Read bytes from image
byte[] data = File.ReadAllBytes(Path.GetFullPath(item));
// Build the package
byte[] dataLength = BitConverter.GetBytes(data.Length);
byte[] package = new byte[4 + data.Length];
dataLength.CopyTo(package, 0);
data.CopyTo(package, 4);
// Send to server
int bytesSent = 0;
int bytesLeft = package.Length;
while (bytesLeft > 0)
{
int nextPacketSize = (bytesLeft > bufferSize) ? bufferSize : bytesLeft;
netS.Write(package, bytesSent, nextPacketSize);
bytesSent += nextPacketSize;
bytesLeft -= nextPacketSize;
}
}
writer.Close();
netS.Close();
}
谢谢你,任何能帮助我的人 您可能希望实现并确认服务器已接收到1个文件。然后指示客户端发送下一个文件。据我所知,你只是一次发送所有文件。下面是确认的一个简单实现。您应该能够为您的场景获取相关部分
//
/* Server Program */
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
public class serv {
public static void Main() {
try {
IPAddress ipAd = IPAddress.Parse("172.21.5.99");
// use local m/c IP address, and
// use the same in the client
/* Initializes the Listener */
TcpListener myList=new TcpListener(ipAd,8001);
/* Start Listeneting at the specified port */
myList.Start();
Console.WriteLine("The server is running at port 8001...");
Console.WriteLine("The local End point is :" +
myList.LocalEndpoint );
Console.WriteLine("Waiting for a connection.....");
Socket s=myList.AcceptSocket();
Console.WriteLine("Connection accepted from " + s.RemoteEndPoint);
byte[] b=new byte[100];
int k=s.Receive(b);
Console.WriteLine("Recieved...");
for (int i=0;i<k;i++)
Console.Write(Convert.ToChar(b[i]));
ASCIIEncoding asen=new ASCIIEncoding();
s.Send(asen.GetBytes("The string was recieved by the server."));
Console.WriteLine("\nSent Acknowledgement");
/* clean up */
s.Close();
myList.Stop();
}
catch (Exception e) {
Console.WriteLine("Error..... " + e.StackTrace);
}
}
}
---------------------------------------------------------------------------
/* Client Program */
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Net.Sockets;
public class clnt {
public static void Main() {
try {
TcpClient tcpclnt = new TcpClient();
Console.WriteLine("Connecting.....");
tcpclnt.Connect("172.21.5.99",8001);
// use the ipaddress as in the server program
Console.WriteLine("Connected");
Console.Write("Enter the string to be transmitted : ");
String str=Console.ReadLine();
Stream stm = tcpclnt.GetStream();
ASCIIEncoding asen= new ASCIIEncoding();
byte[] ba=asen.GetBytes(str);
Console.WriteLine("Transmitting.....");
stm.Write(ba,0,ba.Length);
byte[] bb=new byte[100];
int k=stm.Read(bb,0,100);
for (int i=0;i<k;i++)
Console.Write(Convert.ToChar(bb[i]));
tcpclnt.Close();
}
catch (Exception e) {
Console.WriteLine("Error..... " + e.StackTrace);
}
}
}
//
/*服务器程序*/
使用制度;
使用系统文本;
Net系统;
使用System.Net.Sockets;
公共类服务{
公共静态void Main(){
试一试{
IPAddress ipAd=IPAddress.Parse(“172.21.5.99”);
//使用本地m/c IP地址,以及
//在客户端中使用相同的方法
/*初始化侦听器*/
TcpListener myList=新的TcpListener(ipAd,8001);
/*在指定的端口开始侦听*/
myList.Start();
WriteLine(“服务器正在端口8001上运行…”);
Console.WriteLine(“本地端点为:”+
myList.LocalEndpoint);
WriteLine(“等待连接…”);
套接字s=myList.AcceptSocket();
Console.WriteLine(“从“+s.RemoteEndPoint”接受连接);
字节[]b=新字节[100];
int k=s.Receive(b);
Console.WriteLine(“接收…”);
对于(int i=0;i您有一个混合的二进制/文本协议。这可能会很痛苦。StreamReader
缓冲流的一部分。它需要的时间超过它作为字符串立即返回的时间。您不能将它与其他读卡器混合使用
扔掉所有这些代码,使用更高级的通信机制。例如,WCF和MTOM用于二进制流。或者HTTP
如果您不愿意使用BinaryReader
adBinaryWriter
,那么它们相当容易使用
请注意,当您读取长度时,您假设所有4个字节都将在一次读取中到达。这种假设是错误的。谢谢您的回答,我将尝试使用部分代码:虽然您的读取极不可能填满dataLength
的缓冲区,但不能保证读取所有4个字节。您需要像循环一样进行循环对于您的主要数据(我建议您创建一个静态帮助器方法,其中传入TcpClient和所需的字节数,并返回该大小的完全填充的byte[]
。请参阅我的ReadFully
方法,它使用套接字而不是TcpClient,但主体是相同的)