C# 在套接字连接期间,相同的代码在Windows窗体和Windows服务中产生不同的结果
我有一个充当C# 在套接字连接期间,相同的代码在Windows窗体和Windows服务中产生不同的结果,c#,winforms,sockets,windows-services,C#,Winforms,Sockets,Windows Services,我有一个充当套接字侦听器(服务器端)的代码,我在WinForms和Windows服务中实现它。里面的一切都是一样的,只是我将Windows服务OnStart和OnStop的实现改为buttonStart\u单击WinForm中的buttonStop\u单击 以下是WinForm的代码: private void buttonStart_Click(object sender, EventArgs e) { //should start to listen to the TCP/IP
套接字
侦听器(服务器端)的代码,我在WinForms
和Windows服务
中实现它。里面的一切都是一样的,只是我将Windows服务OnStart
和OnStop
的实现改为buttonStart\u单击WinForm
中的buttonStop\u单击
以下是WinForm
的代码:
private void buttonStart_Click(object sender, EventArgs e) { //should start to listen to the TCP/IP
if (serverHandler.IsMyTargetPortBusy())
return;
try {
serverHandler.InitiateMySocket(); //basically start the socket listening internally
logInput("Start");
} catch { //Fail to do the job. At this moment, don't do anything
//TODO put something for logging
return;
}
}
private void buttonStop_Click(object sender, EventArgs e) {
this.Close(); //Need to change to application exit for the service
}
[2016-01-13 12:41:23.831 UTC] Attempting TCP/IP connection...
[2016-01-13 12:41:23.831 UTC] Attempting to connect to the TCP/IP server...
[2016-01-13 12:41:26.857 UTC] Connected to IP address: 127.0.0.1, Port: 5123
[2016-01-13 12:41:26.857 UTC] Connecting attempt through TCP/IP is successful!
[2016-01-13 12:41:26.889 UTC] Connection attempt: 1
[2016-01-13 12:41:26.889 UTC] Connection attempt is successful!
然后,我通过尝试使用通用TCP-IP客户端应用程序进行连接来测试代码。第一步是连接到套接字
侦听器(服务器端)
建立连接时,客户端将输入一个具有以下代码的方法:
clientHandler.InitiateSocket(myServerIpv4Address, serverPortNo);
if (clientHandler.IsConnected()) {
//Do something
} else {
//Do something, note the error message below
logBox.WriteTimedLog("Connecting attempt through TCP/IP is failed! Timeout Occurs!\n", Color.Red);
}
在clientHandler.InitiateConnect中,我们有
//something else
clientSocket.LoopConnect(5, 3); //In the InitiateConnect
对于类型为Socket
的clientSocket
实例,我有以下方法:
//LoopConnect
public void LoopConnect(int noOfRetry, int attemptPeriodInSeconds) {
int attempts = 0;
while (!this.Connected && attempts < noOfRetry) {
try {
++attempts;
IAsyncResult result = this.BeginConnect(ipv4Address, portNo, endConnect, null);
result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(attemptPeriodInSeconds));
Thread.Sleep(attemptPeriodInSeconds * 1000);
} catch (Exception e) {
//Something else
}
//Something else
}
//Something else
}
//endConnect
private void endConnect(IAsyncResult result) {
try {
this.EndConnect(result);
if (this.Connected) {
this.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(receiveCallback), this);
} else if (ErrorMessageHandler != null) //ErrorMessageHandler is an event handler
ErrorMessageHandler("End of connection attempt, fail to connect...\n");
} catch (Exception e) {
//Something
}
}
//Receive callback
const int MAX_RECEIVE_ATTEMPT = 10;
int receiveAttempt = 0;
private void receiveCallback(IAsyncResult result) {
System.Net.Sockets.Socket socket = null;
try {
socket = (System.Net.Sockets.Socket)result.AsyncState;
if (socket.Connected) {
int received = socket.EndReceive(result);
if (received > 0) {
receiveAttempt = 0;
byte[] data = new byte[received];
Buffer.BlockCopy(buffer, 0, data, 0, data.Length);
//something else
socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(receiveCallback), socket);
} else if (receiveAttempt < MAX_RECEIVE_ATTEMPT) {
++receiveAttempt;
socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(receiveCallback), socket);
} else { //completely fails!
if (ErrorMessageHandler != null) //Note the error message
ErrorMessageHandler("receiveCallback is failed!\n");
receiveAttempt = 0;
this.Close();
}
}
} catch (Exception e) {
//Something else
}
}
令我惊讶的是,当连接到服务器时,我从WinForms
得到的结果与从Windows服务得到的结果不同
这是服务器处于WinForm
时的我的客户端消息:
private void buttonStart_Click(object sender, EventArgs e) { //should start to listen to the TCP/IP
if (serverHandler.IsMyTargetPortBusy())
return;
try {
serverHandler.InitiateMySocket(); //basically start the socket listening internally
logInput("Start");
} catch { //Fail to do the job. At this moment, don't do anything
//TODO put something for logging
return;
}
}
private void buttonStop_Click(object sender, EventArgs e) {
this.Close(); //Need to change to application exit for the service
}
[2016-01-13 12:41:23.831 UTC] Attempting TCP/IP connection...
[2016-01-13 12:41:23.831 UTC] Attempting to connect to the TCP/IP server...
[2016-01-13 12:41:26.857 UTC] Connected to IP address: 127.0.0.1, Port: 5123
[2016-01-13 12:41:26.857 UTC] Connecting attempt through TCP/IP is successful!
[2016-01-13 12:41:26.889 UTC] Connection attempt: 1
[2016-01-13 12:41:26.889 UTC] Connection attempt is successful!
这是服务器处于Windows服务中时的“我的客户端”消息:
[2016-01-13 12:42:14.464 UTC] Attempting TCP/IP connection...
[2016-01-13 12:42:14.480 UTC] Attempting to connect to the TCP/IP server...
[2016-01-13 12:42:17.558 UTC] Connecting attempt through TCP/IP is failed! Timeout Occurs!
[2016-01-13 12:42:17.558 UTC] receiveCallback is failed!
[2016-01-13 12:42:20.245 UTC] Attempting TCP/IP connection...
[2016-01-13 12:42:20.245 UTC] Attempting to connect to the TCP/IP server...
[2016-01-13 12:42:23.261 UTC] Connected to IP address: 127.0.0.1, Port: 5123
[2016-01-13 12:42:23.261 UTC] Connecting attempt through TCP/IP is successful!
[2016-01-13 12:42:23.277 UTC] Connection attempt: 1
[2016-01-13 12:42:23.277 UTC] Connection attempt is successful!
问题
在WinForms
应用程序中,连接在第一次尝试时工作。但是在Windows服务中
我第一次尝试总是失败,必须重复第二次才能连接,尽管在内部,第一次失败意味着我已经重复了10次连接尝试(查看receiveCallback
code)
现在,由于客户端生成的错误消息
[2016-01-13 12:42:17.558 UTC] Connecting attempt through TCP/IP is failed! Timeout Occurs!
[2016-01-13 12:42:17.558 UTC] receiveCallback is failed!
我设法缩小了导致错误的代码部分:
第一个来自这里
clientHandler.InitiateSocket(myServerIpv4Address, serverPortNo);
if (clientHandler.IsConnected()) {
//Do something
} else {
//Do something, note the error message below
logBox.WriteTimedLog("Connecting attempt through TCP/IP is failed! Timeout Occurs!\n", Color.Red);
}
还有这里的第二个:
//Receive callback
const int MAX_RECEIVE_ATTEMPT = 10;
int receiveAttempt = 0;
private void receiveCallback(IAsyncResult result) {
System.Net.Sockets.Socket socket = null;
try {
socket = (System.Net.Sockets.Socket)result.AsyncState;
if (socket.Connected) {
int received = socket.EndReceive(result);
if (received > 0) {
receiveAttempt = 0;
byte[] data = new byte[received];
Buffer.BlockCopy(buffer, 0, data, 0, data.Length);
//something else
socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(receiveCallback), socket);
} else if (receiveAttempt < MAX_RECEIVE_ATTEMPT) {
++receiveAttempt;
socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(receiveCallback), socket);
} else { //completely fails!
if (ErrorMessageHandler != null) //Note the error message
ErrorMessageHandler("receiveCallback is failed!\n");
receiveAttempt = 0;
this.Close();
}
}
} catch (Exception e) {
//Something else
}
}
//接收回调
const int MAX_RECEIVE_trunt=10;
int receivetrust=0;
私有void receiveCallback(IAsyncResult结果){
System.Net.Sockets.Socket Socket=null;
试一试{
套接字=(System.Net.Sockets.socket)result.AsyncState;
if(插座连接){
int received=socket.EndReceive(结果);
如果(收到>0){
receivetrust=0;
字节[]数据=新字节[已接收];
块复制(Buffer,0,data,0,data.Length);
//别的
socket.BeginReceive(buffer,0,buffer.Length,SocketFlags.None,新异步回调(receiveCallback),socket);
}否则如果(接收尝试<最大接收尝试){
++接受尝试;
socket.BeginReceive(buffer,0,buffer.Length,SocketFlags.None,新异步回调(receiveCallback),socket);
}否则{//完全失败!
if(ErrorMessageHandler!=null)//注意错误消息
ErrorMessageHandler(“receiveCallback失败!\n”);
receivetrust=0;
这个。关闭();
}
}
}捕获(例外e){
//别的
}
}
可悲的是,虽然我可以缩小错误的来源,但我无法解释原因,因此也不知道如何解决它。有人知道为什么吗
其他信息:
- 起初,我认为这可能是因为服务启动的时间不够长。但即使我已经等了几分钟,结果也是一样的。这证明我错了