我在C#应用程序中使用BeginSend和BeginReceive。它是一个客户端侦听器,只接收来自服务器的数据。我正在使用BeginReceive来获取数据。
但我发现只接受接收不足以使连接保持活跃和稳定。因此,我决定让我的应用程序始终ping服务器以使用BeginSend保持连接活动。
以下是我的代码:
private void timer1_Tick(object sender, EventArgs e)
{
DataProcess();
}
public Socket _serverSocket = null;
private byte[] _recieveBuffer = new byte[128];
byte[] AllBytes;
void DataProcess()
{
//TimeSpan ts;
try
{
//Thread.Sleep(100);
if (_serverSocket == null || sockState == MySocketState.Disconnected)
{
Console.WriteLine("Trying to connect...");
SetupServer();
}
else
{
AllBytes = ASCIIEncoding.ASCII.GetBytes(COM_DeviceIsOnline);
_serverSocket.BeginSend(AllBytes, 0, AllBytes.Length, SocketFlags.None, new AsyncCallback(SendCallback), null);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
private void SetupServer()
{
try
{
_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_serverSocket.Connect(_sIP, Int32.Parse(_sPort));
}
catch (SocketException ex)
{
Console.WriteLine(ex.Message);
}
if (_serverSocket.Connected)
{
sockState = MySocketState.Connected;
browser.ExecuteScriptAsync("svrConnect();");
Console.WriteLine("Server connected...");
_serverSocket.BeginReceive(_recieveBuffer, 0, _recieveBuffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null);
}
}
void SendCallback(IAsyncResult ar)
{
try
{
int bytesSent = _serverSocket.EndSend(ar);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
private void ReceiveCallback(IAsyncResult AR)
{
try
{
if (_serverSocket == null)
_serverSocket = (Socket)AR.AsyncState;
//Check how much bytes are recieved and call EndRecieve to finalize handshake
int recieved = _serverSocket.EndReceive(AR);
if (recieved <= 0)
{
CloseSocket();
return;
}
//Copy the recieved data into new buffer , to avoid null bytes
byte[] recData = new byte[recieved];
Buffer.BlockCopy(_recieveBuffer, 0, recData, 0, recieved);
string strData = ASCIIEncoding.ASCII.GetString(recData);
Console.WriteLine(strData);
//Process data here the way you want , all your bytes will be stored in recData
int nSOHPos = -1;
int nSTXPos = -1;
int nETXPos = -1;
int nEOTPos = -1;
nSOHPos = Array.IndexOf(recData, SOH);
nSTXPos = Array.IndexOf(recData, STX);
nETXPos = Array.IndexOf(recData, ETX);
nEOTPos = Array.IndexOf(recData, EOT);
if ((nSOHPos == -1) || (nSTXPos == -1) || (nETXPos == -1) || (nEOTPos == -1))
{
CloseSocket();
return;
}
if (nSOHPos > nSTXPos ||
nSTXPos > nETXPos ||
nETXPos > nEOTPos)
{
CloseSocket();
return;
}
if ((nETXPos - nSTXPos) < 6)
{
CloseSocket();
return;
}
string _sCommand = ASCIIEncoding.ASCII.GetString(recData, nSTXPos + 6, 2);
if ((_sCommand == "CN") || (_sCommand == "CL") || (_sCommand == "CR"))
{
nDept = int.Parse(ASCIIEncoding.ASCII.GetString(recData, nSTXPos + 12, 2));
if (nDept != dept_id) return;
nCntr = int.Parse(ASCIIEncoding.ASCII.GetString(recData, nSTXPos + 14, 2));
nServ = int.Parse(ASCIIEncoding.ASCII.GetString(recData, nSTXPos + 16, 2));
sQnum = ASCIIEncoding.ASCII.GetString(recData, nSTXPos + 8, 4);
string[] sSplit = strData.Split('^');
string sCusName = sSplit[1];
//if (_sCommand == "CR") sCusName = " ";
Console.WriteLine("Dept ID = " + nDept);
Console.WriteLine("Cntr ID = " + nCntr);
Console.WriteLine("Serv ID = " + nServ);
Console.WriteLine("Queue No = " + sQnum);
Console.WriteLine("Cus Name = " + sCusName);
var script = string.Format("nextCall(\'{0}\', {1}, {2});", sQnum, nCntr, nServ);
browser.ExecuteScriptAsync(script);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
CloseSocket();
}
finally
{
try
{
//Start receiving again
if (_serverSocket != null)
_serverSocket.BeginReceive(_recieveBuffer, 0, _recieveBuffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null);
//theDevSock.BeginReceive(_recieveBuffer, 0, _recieveBuffer.Length, SocketFlags.None, ReceiveCallback, theDevSock);
}
catch (Exception ex2)
{ }
}
}
public void CloseSocket()
{
try
{
if (_serverSocket != null)
{
if (_serverSocket.Connected)
_serverSocket.Shutdown(SocketShutdown.Both);
_serverSocket.Close();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
_serverSocket = null;
sockState = MySocketState.Disconnected;
browser.ExecuteScriptAsync("svrDisconnect();");
}
我的应用程序开始连接到服务器。连接到服务器后,它将开始ping服务器。但我发现每次使用BeginSend ping服务器后,错误“线程0x1ff0已经退出代码259(0x103)。”并且将断开与服务器的连接,我的应用程序将重新尝试再次连接服务器。然后在成功连接并再次ping服务器后,它再次断开连接。
我可以知道我的编码是否写得正确?我可以像这样使用BeginSend ping服务器吗?
答案 0 :(得分:0)
我添加了以下代码来发送ping:
private void timer2_Tick(object sender, EventArgs e)
{
pingServer();
}
void pingServer()
{
if (_serverSocket != null || sockState == MySocketState.Connected)
{
Console.WriteLine("Ping Server");
AllBytes = ASCIIEncoding.ASCII.GetBytes(COM_DeviceIsOnline);
//_serverSocket.BeginSend(AllBytes, 0, AllBytes.Length, SocketFlags.None, new AsyncCallback(SendCallback), null);
SendTCPData(0x01, 1, 1, 1, "AA", "");
}
}
public bool SendTCPData(byte bySequenceNo, int nSlaveID, int nDeviceID,
int nStatus, String strCommand, String strData)
{
return SendTCPData(ACK, bySequenceNo, nSlaveID, nDeviceID, nStatus, strCommand, strData);
}
public bool SendTCPData(byte byTypeCode, byte bySequenceNo,
int nSlaveID, int nDeviceID,
int nStatus, String strCommand,
String strData)
{
return SendTCPData(byTypeCode, bySequenceNo, nSlaveID, nDeviceID,
nStatus, strCommand, strData, 0);
}
public bool SendTCPData(byte byTypeCode, byte bySequenceNo,
int nSlaveID, int nDeviceID,
int nStatus, String strCommand, String strData, int nProtocolType)
{
byte[] AllBytes;
String strTemp;
try
{
strTemp = nSlaveID.ToString("0#") +
nDeviceID.ToString("0#") +
nStatus.ToString() +
strCommand + strData;
if (nProtocolType == 0)
{
AllBytes = new byte[strTemp.Length + 7];
AllBytes[0] = SOH;
AllBytes[1] = byTypeCode;
AllBytes[2] = (byte)((int)bySequenceNo | 0x80);
AllBytes[3] = STX;
ASCIIEncoding.ASCII.GetBytes(strTemp).CopyTo(AllBytes, 4);
AllBytes[AllBytes.Length - 3] = ETX;
AllBytes[AllBytes.Length - 2] = 128;
AllBytes[AllBytes.Length - 1] = EOT;
}
else
{
AllBytes = new byte[strTemp.Length + 6];
AllBytes[0] = SOH;
AllBytes[1] = STX;
ASCIIEncoding.ASCII.GetBytes(strTemp).CopyTo(AllBytes, 2);
AllBytes[AllBytes.Length - 4] = ETX;
AllBytes[AllBytes.Length - 3] = ETX;
AllBytes[AllBytes.Length - 2] = 128;
AllBytes[AllBytes.Length - 1] = EOT;
}
//Debug.WriteLine("Sending data to " + _sIPAddr + " -> " + ASCIIEncoding.ASCII.GetString(AllBytes));
return SendByte(AllBytes, AllBytes.Length);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
return false;
}
public bool SendByte(byte[] pByteData, int nLength)
{
try
{
if (_serverSocket == null) return false;
if (!_serverSocket.Connected) return false;
Console.WriteLine("SendByte = " + ASCIIEncoding.ASCII.GetString(pByteData, 0, nLength));
//Debug.WriteLine("SendByte Length= " + nLength.ToString() );
_serverSocket.BeginSend(pByteData, 0, nLength, SocketFlags.None,
SendCallback, _serverSocket);
//dtLastActivity = DateTime.Now;
return true;
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
CloseSocket();
}
return false;
}
我使用30秒计时器发送ping,只要它与服务器有连接,它就会发送ping。现在,它已经可以检测到未插入的电缆。
我可以知道你们对这个答案的看法是什么吗?