套接字关闭后,我似乎无法重新连接。网上有几个答案,但似乎都没有。
我有一个使用以下代码连接的程序,这个代码几乎从Microsoft的例子中解脱出来。
private void StartClient()
{
DateTime time = DateTime.Now; // Use current time
string format = "ddd-d-HH:mm-ss";
string timeString = time.ToString(format);
// Connect to a remote device.
try
{
if (client != null)
Stop();
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
var state = new StateObject { workSocket = client };
// Connect to the remote endpoint.
client.BeginConnect(AprsConfig.URI, AprsConfig.Port,
new AsyncCallback(ConnectCallback), client);
connectDone.WaitOne();
string logInString = string.Format("user {0} pass {1} vers Web-{3} 1.0 filter {2}\r\n",
AprsConfig.Callsign,
AprsConfig.Password,
AprsConfig.Filter,
timeString);
// Send data to the remote device.
appendToDebugFile("Sent to server: " + logInString);
Send(client, logInString);
sendDone.WaitOne();
// Receive the response from the remote device.
Receive(client);
}
catch (Exception e)
{
// Console.WriteLine(e.ToString());
appendToDebugFile("StartClient failed : " + e.ToString());
if (retryCount < 10)
{
appendToDebugFile("Attempt to restart again");
retryCount++;
restartClient
}
}
retryCount=0;
}
第一次正确连接没有问题。 Receive()再次调用自己,依此类推。 我不认为这是相关的,但这里是代码
private void Receive(Socket client)
{
try
{
// Create the state object.
StateObject state = new StateObject();
state.workSocket = client;
// Begin receiving the data from the remote device.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
catch (Exception e)
{
//Console.WriteLine(e.ToString());
appendToDebugFile("Receive failed : " + e.ToString());
}
}
和
private void ReceiveCallback(IAsyncResult ar)
{
try
{
// Retrieve the state object and the client socket
// from the asynchronous state object.
var state = (StateObject)ar.AsyncState;
if (!state.workSocket.Connected)
{
reStartClient("Error: state.workSocket.Connected =false - Restarting");
return;
}
var client = state.workSocket;
// Read data from the remote device.
var bytesRead = client.EndReceive(ar);
if (bytesRead == 0)
{
reStartClient("ERROR: bytes==0 - Restarting");
return;
}
// quickly store the buffer
storeBytes buff = new storeBytes(state.buffer, bytesRead);
byteQueue.Enqueue(buff);
string data = Encoding.ASCII.GetString(state.buffer, 0, bytesRead);
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
// setoff the readBytes Thread
readBytesWaitHandle.Set();
}
catch(IOException e)
{
appendToDebugFile("ReceiveCallback failed : " + e.ToString());
}
}
我正确或错误地假设如果我读取零字节,则连接失败 我尝试关闭连接并重新开始。这是我从另一个Stackoverflow答案得到的代码。
private void reStartClient(string reason)
{
appendToDebugFile(reason);
if (client != null && client.Connected)
{
client.Shutdown(SocketShutdown.Both);
client.Disconnect(true);
if (client.Connected)
appendToDebugFile("We're still connnected");
else
appendToDebugFile("We're disconnected");
client.Close();
}
client = null;
// appendToDebugFile("Waiting 10 secs");
// System.Threading.Thread.Sleep(10000);
StartClient();
}
正如你所看到的,我一直在尝试延迟,但这种做法并没有奏效。
重新启动后,它通过StartClient似乎连接但在尝试发送时抛出错误。这是日志文件的一部分
尝试重新启动Socket连接到37.187.40.234:14580 停止13/08/2014 14:18:18我们已经断开连接发送到服务器:用户 2E0ATJ传递-1 vers Web-Wed-13-14:18-18 1.0过滤器r / 51.6 / - .8 / 2000 -q / C
StartClient失败:System.Net.Sockets.SocketException(0x80004005): 由于套接字是,因此不允许发送或接收数据的请求 未连接和(使用sendto在数据报套接字上发送时) call)WebAPRS.PacketListener.Send没有提供地址(Socket 客户端,字符串数据)在c:\ Users \ Alan \ Documents \ Visual Studio中 2013 \ Projects \ WebAPRS \ WebAPRS \ Connection.cs:第188行 c:\ Users \ Alan \ Documents \ Visual中的WebAPRS.PacketListener.StartClient() Studio 2013 \ Projects \ WebAPRS \ WebAPRS \ Connection.cs:第64行尝试 重新启动已停止13/08/2014 14:18:18发送到服务器:用户2E0ATJ 传1-vers Web-Wed-13-14:18-18 1.0过滤器r / 51.6 / - .8 / 2000 -q / C
StartClient失败:System.Net.Sockets.SocketException(0x80004005): 由于套接字是,因此不允许发送或接收数据的请求 未连接和(使用sendto在数据报套接字上发送时) call)WebAPRS.PacketListener.Send没有提供地址(Socket 客户端,字符串数据)在c:\ Users \ Alan \ Documents \ Visual Studio中 2013 \ Projects \ WebAPRS \ WebAPRS \ Connection.cs:第188行 c:\ Users \ Alan \ Documents \ Visual中的WebAPRS.PacketListener.StartClient() Studio 2013 \ Projects \ WebAPRS \ WebAPRS \ Connection.cs:第64行尝试 再次重启停止13/08/2014 14:18:18
希望有人可以告诉我我做错了什么。
答案 0 :(得分:0)
最有可能connectDone
是ManualResetEvent
,它在之前的连接尝试中被置于信号状态,并且从未重置过。这会导致WaitOne()
无法阻止,并且代码会在建立连接之前尝试发送数据。
您可以在连接之前重置它:
// Connect to the remote endpoint.
connectDone.Reset();
client.BeginConnect(AprsConfig.URI, AprsConfig.Port, new AsyncCallback(ConnectCallback), client);
connectDone.WaitOne();
如果没有其他线程监视AutoResetEvent
,则可以使用connectDone
。