这个问题可能很难回答,或者有人知道一个共同的原因。
我有1个服务器,5个客户端;
Socket client
Socket listener
客户端每5000 MS通过套接字检查服务器(Windows 7)上的文件,如果发现客户端通过套接字接收文件。
据我所知,只有Windows Server一次可以处理两个以上的异步文件传输。
我的问题是,客户端随机开始接收文件。所有客户一般都很好。有一段时间,客户端将停止接收文件,而不是完成文件传输,我的客户端程序只是挂起而且永远不会完成。
我无法在开发环境中重现这一点。我用半文件文件,100次发送测试了它,我从来没有收到错误。
我的问题是,是否有可能在Windows 7上有一些协议阻止我从服务器发送文件。
我接收客户端的电话是非常冗长的,但现在是。我认为问题不在代码中。
非常感谢任何帮助。我的老板即将拥有我的脖子:(
private static void ReceiveCallback(IAsyncResult ar)
{
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
try
{
// Retrieve the state object and the client socket
// from the asynchronous state object.
// Read data from the remote device.
int bytesRead = client.EndReceive(ar);
state.totalBytesRead += bytesRead;
if (bytesRead > 0)
{
if (state.flag == 0)
{
if (state.totalBytesRead >= 8)
{
// we know we put the msgLen / prefixLen as the first 8 bytes on the stream
state.msgLen = BitConverter.ToInt32(state.buffer, 0);
state.prefixLen = BitConverter.ToInt32(state.buffer, 4);
state.flag = 1;
// good to process the first 2 integer values on the stream
//state.sb.Append(Encoding.ASCII.GetString(state.buffer, 8, bytesRead));
int prefixRequestBytes = state.prefixLen;
if (prefixRequestBytes > StateObject.BufferSize)
prefixRequestBytes = StateObject.BufferSize;
state.lastSendByteCount = prefixRequestBytes;
state.totalBytesRead = 0;
// start re-writing to the begining of the buffer since we saved
client.BeginReceive(state.buffer, 0, prefixRequestBytes, 0, new AsyncCallback(ReceiveCallback), state);
return;
}
else
{
int bytesToSend = state.lastSendByteCount - bytesRead;
state.lastSendByteCount = bytesToSend;
// need to receive atleast first 8 bytes to continue
// Get the rest of the data.
client.BeginReceive(state.buffer, state.totalBytesRead, bytesToSend, 0, new AsyncCallback(ReceiveCallback), state);
return;
}
}
if (state.flag == 1)
{
// we are expexing to process the prefix
if (state.totalBytesRead >= state.prefixLen)
{
// we are good to process
// Lets always assume that our prefixMsg can fit into our prefixbuffer ( we wont send greater than prefixbuffer)
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, state.prefixLen));
string prefixMsg = state.sb.ToString();
if (!String.IsNullOrEmpty(prefixMsg))
{
state.cmd = parseXml("CMD", prefixMsg);
state.fName = parseXml("FNAME", prefixMsg);
// File requester should never get a del command
//if (state.cmd == "DEL")
//{
// Console.WriteLine("Processing 'DEL' command..");
// // delete the file
// string filePath = "C:\\" + locationFolder + "\\" + state.fName;
// if (System.IO.File.Exists(filePath))
// {
// System.IO.File.Delete(filePath);
// }
// Console.WriteLine("Deleted file");
// // receiveDone.Set();
// requestTimer.Start();
// return;
//}
//else
if (state.cmd == "SND")
{
Console.WriteLine("Processing 'SND' command..");
// let it rip
if (state.msgLen == 0) // no files
{
Console.WriteLine("No files on server");
requestTimer.Start();
return;
}
}
}
state.receivedPath = importTempFolder + state.fName;
// receive the rest of the file
if (System.IO.File.Exists(state.receivedPath))
{
Console.WriteLine("Deleting temp file: " + state.receivedPath + " for re-write");
System.IO.File.Delete(state.receivedPath);
}
state.flag++;
int msgRequestBytes = state.msgLen;
if (msgRequestBytes > StateObject.BufferSize)
msgRequestBytes = StateObject.BufferSize;
state.lastSendByteCount = msgRequestBytes;
state.totalBytesRead = 0;
// should be good to process the msg now
// start re-writing to the begining of the buffer since we saved
client.BeginReceive(state.buffer, 0, msgRequestBytes, 0, new AsyncCallback(ReceiveCallback), state);
return;
}
else
{
int bytesToSend = state.lastSendByteCount - bytesRead;
state.lastSendByteCount = bytesToSend;
// request the rest of the prefix
// Get the rest of the data.
client.BeginReceive(state.buffer, state.totalBytesRead, bytesToSend, 0, new AsyncCallback(ReceiveCallback), state);
return;
}
}
// we are expecting to process the file
if (state.flag > 1)
{
if (state.totalBytesRead >= state.msgLen)
{
Console.WriteLine("Writing final {0} bytes to server", bytesRead);
using (FileStream fs = new FileStream(state.receivedPath, FileMode.Append, FileAccess.Write))
using (BinaryWriter writer = new BinaryWriter(fs))
{
//BinaryWriter writer = new BinaryWriter(File.Open(state.receivedPath, FileMode.Append, FileAccess.Write, FileShare.None));
writer.Write(state.buffer, 0, bytesRead);
fs.Flush();
// writer.Close();
}
// GC.Collect();
// if temp folder exists, import will exists because its inside it
string destFile = importFolder + state.fName;
if (System.IO.File.Exists(destFile))
{
Console.WriteLine("Deleting file for re-write in importin: \n" + destFile);
System.IO.File.Delete(destFile);
}
Console.WriteLine("Moving file: \n" + state.receivedPath);
System.IO.File.Copy(state.receivedPath, destFile);
Console.WriteLine("Deleting file from temp: \n" + state.receivedPath + importTempFolder + state.fName);
System.IO.File.Delete(state.receivedPath);
if (state.cmd == "SND")
{
Console.WriteLine("Sending 'DEL' command.");
SendDeleteResponse(client, state.fName);
Console.WriteLine("Finished reading to file: " + state.receivedPath);
// receiveDone.Set();
requestTimer.Start();
return;
}
Console.WriteLine("Finished reading file");
client.Shutdown(SocketShutdown.Both);
client.Close();
// receiveDone.Set();
requestTimer.Start();
}
else
{
//Console.WriteLine("Reading {0} bytes from server...", bytesRead);
// Padd these bytes
using (FileStream fs = new FileStream(state.receivedPath, FileMode.Append, FileAccess.Write))
using (BinaryWriter writer = new BinaryWriter(fs))
{
//BinaryWriter writer = new BinaryWriter(File.Open(state.receivedPath, FileMode.Append, FileAccess.Write, FileShare.None));
writer.Write(state.buffer, 0, bytesRead);
fs.Flush();
// writer.Close();
}
// GC.Collect();
// get how many more bytes are left to read
int bytesToSend = state.msgLen - bytesRead;
if (bytesToSend > StateObject.BufferSize)
bytesToSend = StateObject.BufferSize;
client.BeginReceive(state.buffer, 0, bytesToSend, 0, new AsyncCallback(ReceiveCallback), state);
return;
}
}
}
else
{
// All the data has arrived;
}
}
catch (Exception e)
{
Console.WriteLine("HERE5 " + e.Message);
client.Close();
// receiveDone.Set();
requestTimer.Start();
return;
}
}