最近在用C#写基于tcp、udp进行数据发送与接收的程序。由于在tcp通信中客户端与服务器端的通信是基于握手协议的,所以一旦客户端断开与服务器端的连接时,服务器端需要检测客户端的这个动作,并返回到端口侦听状态而不是继续处于读缓冲区数据状态,否则客户端下次就无法与服务器再次连接了。下面是我写的tcp服务器端的部分程序():
private void Listen()
{
tcpServerListener.Start();
while (listenStatusFlag)//网络侦听标志位,用于手动关闭端口侦听服务
{
stRead = tcpServerListener.AcceptSocket();//接收tcp连接的端口连接请求,客户端断开连接时需要返回到这条语句
SaveReceivedData();
}
}
private void SaveReceivedData()
{
EndPoint remoteEP = stRead.RemoteEndPoint;
IPEndPoint remoteIP = (IPEndPoint)(remoteEP);
//获取请求的远程计算机名称
string sHostName = "";
/*防止发生在用DNS反查主机名时失败的情况*/
try
{
IPHostEntry host = Dns.GetHostByAddress(remoteIP.Address);
sHostName = host.HostName;
}
catch (System.Exception ex)
{
sHostName = "**模块";
}
byte[] recData = new byte[1000000];
string recvStr = "";
string last_Rec = "";//因为从Socket端口中取数据时,无法确保每次从缓冲区中取得整单位的完整数据(比如说,发送端每次发送4字节的数据串,而你本次从缓冲区中可能取得7个字节数据,其中的末尾三个字节数据(即该变量)得配合下次从缓冲区中取得数据平凑才有用
int bytes = 0;
try
{
while(stRead.Poll(-1,SelectMode.SelectRead))//网络侦听标志,检测客户端是否断开连接
{
try
{
//从缓冲区中读一次数据
bytes = stRead.Receive(recData, recData.Length, 0);
if (bytes>0 && swWriter!=null)
{
UTF8Encoding encodeType=new UTF8Encoding();
swWriter.Write(encodeType.GetString(recData, 0, bytes));
swWriter.Flush();
}
else
{
stRead.Shutdown(SocketShutdown.Both);
stRead.Close();//结束与客户端的连接,返回到侦听状态
}
}
catch (System.Exception ex)
{
return;//客户端异常关闭时返回到侦听状态
//MessageBox.Show("网络侦听接收出错!");
}
if (bytes <= 0)
continue;
recvStr = Encoding.UTF8.GetString(recData, 0, bytes);
/*以下是对接收到的数据的具体数据,每个人对数据处理方式不一样,这里就不贴了*/
}
}
}