joe_pool_is
Contributor
I have an application that I have written for my application distributed throughout the company to send data to me through our Windows 2003 server (running IIS 6.0). Small text messages get through, but larger messages containing more data (about 20 KB) are not getting through.
I set the byte buffer to the TCP Clients buffer size. I noticed that my data was being received on the server; however, it only looped through the receive routine once, and my large files were always exactly the size of the buffer size, or 8 KB on our server. In other words, my code only makes it through one loop before the server closes the socket connection.
Thinking there might be an issue with filling the whole buffer, I tried limiting my read/writes to just 1 KB but this only resulted in our server closing the socket after receiving 1 KB before closing the connection.
I send the servers error message back to the client so I can view it. The specific error message that I receive from the client is: Unable to write data to the transport connection: An established connection was aborted by the software in your host machine.
I updated my server application so that the underlying TCP Socket would use keep alives with this line:
Now, whenever I attempt sending a message, the client receives the error: Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host.
Our Network Administrator has told me that he does not have a firewall or any ports blocked on this internal server.
Googling the error I received, I found many posts suggesting people try to telnet into the server. I used their directions to telnet into the server, but I am not sure what to make of the response:
I have tried other ports in code and through Telnet including 25, 80, and 8080. Telnet kicks out port 25, but my application seems to read the first loop no matter what port I tell it to run.
Here is my code that runs on the clients:
Here is my code that runs on the server:
Why doesnt my application continue reading from the TCP Client? Have I neglected to set something that tells the Socket to stay open until I have finished? The server code never sees an exception because the TCP Client is never stopped, so I know there is no error.
Our Network Administrator has not received his Associates Degree yet, so if it turns out to be an issue with the Server, kindly be detailed in your description of how to resolve this, because we might not understand what youre saying.
Thanks for helping!
~Joe
I set the byte buffer to the TCP Clients buffer size. I noticed that my data was being received on the server; however, it only looped through the receive routine once, and my large files were always exactly the size of the buffer size, or 8 KB on our server. In other words, my code only makes it through one loop before the server closes the socket connection.
Thinking there might be an issue with filling the whole buffer, I tried limiting my read/writes to just 1 KB but this only resulted in our server closing the socket after receiving 1 KB before closing the connection.
I send the servers error message back to the client so I can view it. The specific error message that I receive from the client is: Unable to write data to the transport connection: An established connection was aborted by the software in your host machine.
I updated my server application so that the underlying TCP Socket would use keep alives with this line:
PHP:
client.Client.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.KeepAlive, true);
Now, whenever I attempt sending a message, the client receives the error: Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host.
Our Network Administrator has told me that he does not have a firewall or any ports blocked on this internal server.
Googling the error I received, I found many posts suggesting people try to telnet into the server. I used their directions to telnet into the server, but I am not sure what to make of the response:
C:\> telnet
Welcome to Microsoft Telnet Client
Escape Character is CTRL+]
Microsoft Telnet> open cpapp 500
Connecting To cpapp
This is all I get. I never get an error, and Microsofts Telnet screen will eventually change to Press any key to continue
I guess it times out, but my code is somehow able to connect.Welcome to Microsoft Telnet Client
Escape Character is CTRL+]
Microsoft Telnet> open cpapp 500
Connecting To cpapp
I have tried other ports in code and through Telnet including 25, 80, and 8080. Telnet kicks out port 25, but my application seems to read the first loop no matter what port I tell it to run.
Here is my code that runs on the clients:
Code:
int sendUsingTcp(string location) {
string result = string.Empty;
try {
using (FileStream fs = new FileStream(location, FileMode.Open, FileAccess.Read)) {
using (TcpClient client = new TcpClient(GetHostIP, CpAppDatabase.ServerPortNumber)) {
byte[] riteBuf = new byte[client.SendBufferSize];
byte[] readBuf = new byte[client.ReceiveBufferSize];
using (NetworkStream ns = client.GetStream()) {
if ((ns.CanRead == true) && (ns.CanWrite == true)) {
int len;
string AOK = string.Empty;
do {
len = fs.Read(riteBuf, 0, riteBuf.Length);
ns.Write(riteBuf, 0, len);
int nsRsvp = ns.Read(readBuf, 0, readBuf.Length);
AOK = Encoding.ASCII.GetString(readBuf, 0, nsRsvp);
} while ((len == riteBuf.Length) && (-1 < AOK.IndexOf("AOK")));
result = AOK;
return 1;
}
return 0;
}
}
}
} catch (Exception err) {
Logger.LogError("Send()", err);
MessageBox.Show(err.Message, "Message Failed", MessageBoxButtons.OK, MessageBoxIcon.Hand, 0);
return -1;
}
}
Here is my code that runs on the server:
Code:
SvrForm.Server = new TcpListener(IPAddress.Any, CpAppDatabase.ServerPortNumber);
void Worker_Engine(object sender, DoWorkEventArgs e) {
BackgroundWorker worker = sender as BackgroundWorker;
string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), Application.CompanyName);
if (Directory.Exists(path) == false) Directory.CreateDirectory(path);
Thread.Sleep(0);
string eMsg = string.Empty;
try {
SvrForm.Server.Start();
do {
using (TcpClient client = SvrForm.Server.AcceptTcpClient()) { // waits until data is avaiable
if (worker.CancellationPending == true) return;
client.Client.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.KeepAlive, true);
string location = Path.Combine(path, string.Format("Acp{0:yyyyMMddHHmmssff}.bin", DateTime.Now));
byte[] buf = new byte[client.ReceiveBufferSize];
try {
using (NetworkStream ns = client.GetStream()) {
if ((ns.CanRead == true) && (ns.CanWrite == true)) {
try {
int len;
byte[] AOK = Encoding.ASCII.GetBytes("AOK");
using (FileStream fs = new FileStream(location, FileMode.Create, FileAccess.Write)) {
do {
len = ns.Read(buf, 0, client.ReceiveBufferSize);
fs.Write(buf, 0, len);
ns.Write(AOK, 0, AOK.Length);
} while ((0 < len) && (ns.DataAvailable == true));
}
byte[] okBuf = Encoding.ASCII.GetBytes("Message Received on Server");
ns.Write(okBuf, 0, okBuf.Length);
} catch (Exception err) {
Global.LogError("ServerForm.cs - Worker_Engine(DoWorkEvent)", err);
byte[] errBuf = Encoding.ASCII.GetBytes(err.Message);
ns.Write(errBuf, 0, errBuf.Length);
}
}
}
} finally {
client.Close();
}
worker.ReportProgress(1, location);
}
} while (worker.CancellationPending == false);
} catch (SocketException) {
// See MSDN: Windows Sockets V2 API Error Code Documentation for detailed description of error code
e.Cancel = true;
} catch (ObjectDisposedException err) {
eMsg = "Worker TcpClient Disposed Error:\r\n" + err.Message;
e.Cancel = true;
e.Result = err;
} catch (InvalidOperationException err) {
eMsg = "Worker Invalid Operation Error:\r\n" + err.Message;
e.Cancel = true;
e.Result = err;
} catch (ThreadAbortException err) { // If I have to call Abort on this thread
eMsg = "Worker Thread Abort Exception:\r\n" + err.Message;
SvrForm.Server.Stop();
e.Cancel = true;
e.Result = err;
} catch (ArgumentNullException err) {
eMsg = "Worker Argument Null Error:\r\n" + err.Message;
e.Cancel = true;
e.Result = err;
} catch (ArgumentOutOfRangeException err) {
eMsg = "Worker ArgumentOutOfRange:\r\n" + err.Message;
e.Cancel = true;
e.Result = err;
} catch (Exception err) {
eMsg = "Worker General Error:\r\n" + err.Message;
e.Cancel = true;
e.Result = err;
} finally {
SvrForm.Server.Stop();
}
}
Our Network Administrator has not received his Associates Degree yet, so if it turns out to be an issue with the Server, kindly be detailed in your description of how to resolve this, because we might not understand what youre saying.
Thanks for helping!
~Joe