我在客户端,服务器端都使用同步socket,客户端正常发送消息没有问题,可以收到,如果客户端只是按了下 Enter 键,服务器端Receive函数就阻塞,不向下执行,客户端由于收不到服务器端返回的消息,也会阻塞。我的想法是在服务器端加个timer,如果3秒后,Receive函数没有执行完毕,就认为超时,然后给客户端发生超时消息,关闭本次Socket连接。但是掉用超时委托函数的时候,导致服务器端推出,请高人指教。
报异常信息为:一个封锁操作被对 WSACancelBlockingCall 的调用中断。
服务端代码
class Class1
{
public static bool flag=false;           //函数Receive执行完毕 flag 置为 true
public static Socket temp=null;          //接受的客户端连接

/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{

try
{
TimerCallback timerCallBack = new TimerCallback(ForeSendMsg);
int port =3001;
string ipstr="127.0.0.1";
IPAddress ip = IPAddress.Parse(ipstr);
IPEndPoint ipe = new IPEndPoint(ip,port);
Socket  s = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
s.Bind(ipe);
s.Listen(50);
Console.WriteLine("begin listen ...." );
while(true)
{
flag = false;
temp=null;

temp = s.Accept();
string receStr;
byte[] receBytes = new byte[1024];
int bytes;
Console.WriteLine("start receive.........");
Timer timer = new Timer(timerCallBack,temp,3000,0);              //设置定时器,3秒之后,如果Receive还没有执行完毕,认为超时,本次不再接受客户端数据,返回给客户端超时消息

bytes=temp.Receive(receBytes,0,receBytes.Length,SocketFlags.Partial);
flag=true;
Console.WriteLine("End receive............");

receStr = Encoding.GetEncoding("utf-8").GetString(receBytes,0,bytes);
Log.WriteLog("test",new StringBuilder(receStr+"\r\n"));
Console.WriteLine("receive msg="+receStr);
string sendstr = "ok!"+"dsssssssssssssss";
byte[] bs = Encoding.ASCII.GetBytes(sendstr);
temp.Send(bs,0,bs.Length,SocketFlags.None);
temp.Shutdown(SocketShutdown.Both);
temp.Close();

}

//s.Close();
}
catch(SocketException se)
{
Log.WriteLog("test",new StringBuilder(se.Message+"\r\n"));
Console.WriteLine("SocketException "+se.Message);
}
catch(Exception ex)
{
Log.WriteLog("test",new StringBuilder(ex.Message+"\r\n"));
Console.WriteLine("Exception "+ex.Message);
}
}
public static void ForeSendMsg(Object tmp)
{
Socket temp = (Socket)tmp;
if(temp!=null&&flag==false&&temp.Connected)
{
temp.Shutdown(SocketShutdown.Receive);
Console.WriteLine("Time is reach");
byte[] arr = Encoding.ASCII.GetBytes("Exception from 1");
temp.Send(arr);
temp.Shutdown(SocketShutdown.Both);
temp.Close();
}
}
}
客户端代码如下
static void Main(string[] args)
{
//
// TODO: 在此处添加代码以启动应用程序
// try
{
int port =3001;
string ipstr="127.0.0.1";
IPAddress ip = IPAddress.Parse(ipstr);
IPEndPoint ipe = new IPEndPoint(ip,port);

while(true)
{
try
{
Socket c= new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
string sendstr = Console.ReadLine();

byte[] sendbyte = Encoding.ASCII.GetBytes(sendstr);
c.Connect(ipe);
c.Send(sendbyte);
string recestr;
byte[] receBytes= new byte[1024];
int bytes;
bytes = c.Receive(receBytes,receBytes.Length,0);
recestr = Encoding.ASCII.GetString(receBytes,0,bytes);
Console.WriteLine("from server msg"+recestr);
c.Shutdown(SocketShutdown.Both);
c.Close();

}
catch(Exception e)
{
Console.WriteLine(e.Message);

}

}
}
catch(SocketException sc)
{
Console.WriteLine("SocketeException "+sc.Message);
}
catch(Exception e)
{
Console.WriteLine("Exception "+e.Message); }
Console.WriteLine("Press Enter to Exit");
   Console.ReadLine();
}