我有一个应用程序为我的应用程序编写,分布在整个公司,通过我们的Windows 2003服务器(运行IIS 6.0)向我发送数据。小文本消息可以通过,但包含更多数据(大约20 KB)的大消息无法通过。TCP客户端连接
我将字节缓冲区设置为TCP客户端的缓冲区大小。我注意到我的数据正在服务器上收到;但是,它只通过接收例程循环一次,而我的大文件总是正好是缓冲区大小的大小,或者我们服务器上的大小为8 KB。换句话说,我的代码只在服务器关闭套接字连接之前通过一个循环。
考虑到填充整个缓冲区可能存在问题,我尝试将读/写限制为1 KB,但这仅导致我们的服务器在关闭连接之前收到1 KB后关闭套接字。
我将服务器的错误信息发送回客户端,以便我可以查看它。我从客户端收到特定的错误信息是:
“Unable to write data to the transport connection: An established connection was aborted by the software in your host machine.”
我更新了我的服务器应用程序,使底层TCP套接字将使用的“保持活动”这一行:
client.Client.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.KeepAlive, true);
现在,每当我试图发送一个消息,在客户端收到错误:
“Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host.”
我们的网络管理员告诉我,他没有防火墙或阻止我们内部的服务器上的任意端口。
使用谷歌搜索错误,我发现帖子暗示人们尝试远程登录到服务器。我用自己的方向远程登录到服务器上,但我不知道该做出响应的是什么:
C:> telnet Welcome to Microsoft Telnet Client
Escape Character is ‘CTRL+]’
Microsoft Telnet> open cpapp 500 Connecting To cpapp…
这是我得到的。我从来没有得到一个错误,微软的Telnet屏幕最终会改变为“按任意键继续......” - 我猜测它超时了,但我的代码以某种方式能够连接。
我已经尝试了代码中的其他端口,并通过Telnet包括25,80,8080.Telnet踢出端口25,但我的应用程序似乎读取第一个循环,不管我告诉它运行哪个端口。
这里是我的代码,在客户端上运行:
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;
}
}
这里是我的代码在服务器上运行:
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);
}
}
}
}
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 (Exception err) {
eMsg = "Worker General Error:\r\n" + err.Message;
e.Cancel = true;
e.Result = err;
} finally {
SvrForm.Server.Stop();
}
}
为什么没有我的应用程序继续从TCP客户端阅读?我有没有忽视设置一些东西,告诉套接字在我完成之前保持打开状态?服务器代码从不会看到异常,因为TCP客户端从不停止,所以我知道没有错误。
我们的网络管理员还没有收到他的同事学位,所以如果事实证明是服务器的问题,请在你的描述中详细说明如何解决这个问题,因为我们可能不明白你在说什么。
我很抱歉这么长时间,但我想确保你们在那里知道我在做什么 - 甚至可以从我的技术中获得一些信息!
感谢您的帮助! 〜乔
没有开玩笑吗?我想现在是有道理的。我一直在想,需要在服务器上设置一些东西。这有助于很多*!谢谢! – jp2code 2009-08-12 13:06:29
我该怎么做? “在发送内容之前的内容长度”我没有发送内容的长度? – 2017-11-28 08:26:48
如果你不知道长度,那么显然你不会发送线上的长度。 – Amy 2017-11-28 22:09:03