同步套接,断开服务器,这样自动链接上
同步套接,断开服务器,这么自动链接上
这个是我的客户端监听代码:
public void BeginListen(string ip, int _port)
{
_IsFinish = true;
_socket = SocekConnection();
IPAddress _ip;
_ip = IPAddress.Parse(ip);
IPEndPoint iep = new IPEndPoint(_ip, _port);
try
{
_socket.Connect(iep);
if (Event_ConnectionState != null)
Event_ConnectionState(true, "");
}
catch (Exception ex)
{
_socket.Close();
_socket = null;
LogInfo.Instance.Log(ex.ToString());
if (Event_ConnectionState != null)
Event_ConnectionState(false, "连接断开!"+ex.Message);
_IsFinish = false;
return;
}
ns = new NetworkStream(_socket, true);
List<byte[]> list = new List<byte[]>();
int tcount = 0;
while (_IsFinish)
{
if (!IsConnected(_socket))
{
if (Event_ConnectionState != null)
{
System.Diagnostics.Trace.WriteLine("服务器连接中断");
Event_ConnectionState(false, "服务器连接中断!");
_IsFinish = false;
return;
}
}
try
{
if (ns.CanRead)
{
_socket.NoDelay = true;
_socket.ReceiveBufferSize = 65406;
Thread.Sleep(50);
while (ns != null && ns.DataAvailable)
{
System.Diagnostics.Trace.WriteLine("============当前NetworkStream开始读取:===========");
byte[] RecFlagBuffer = new byte[2];
ns.Read(RecFlagBuffer, 0, 2);
int ContentSize = RecFlagBuffer[0] << 8 | RecFlagBuffer[1] << 0;
byte[] byteMessage = new byte[ContentSize];
int nscount = 0;
int receivcount = 0;
int first = 0;
int allcount = ContentSize;
int readcount = 0;
while ((nscount = ns.Read(byteMessage, first, allcount)) != 0)
{
System.Diagnostics.Trace.WriteLine("本次接收到的数据大小:" + nscount.ToString());
readcount++;
receivcount += nscount;
if (receivcount >= ContentSize)
break;
first = receivcount;
allcount = ContentSize - receivcount;
}
tcount++;
System.Diagnostics.Trace.WriteLine("本次接收次数:" + tcount.ToString() + " 实际大小:" + ContentSize.ToString() + " 接收到的大小:" + receivcount.ToString());
System.Diagnostics.Trace.WriteLine("byteMessage开始和结束字符:"+byteMessage[0].ToString() + " "+byteMessage[ContentSize-1].ToString());
if (tcount == 1 && ContentSize < 65400)
{
if (EventMessage != null)
{
tcount = 0;
System.Diagnostics.Trace.WriteLine("数据小于65400回发");
EventMessage(byteMessage);
}
}
else
{
if (ContentSize < 65400)
{
list.Add(byteMessage);
if (list.Count > 1)
{
int count = 0;
for (int i = 0; i < list.Count; i++)
{
count += list[i].Length;
}
byte[] msg = new byte[count];
int c = 0;
for (int i = 0; i < list.Count; i++)
{
if (i == 0)
{
list[i].CopyTo(msg, 0);
}
else
{
c += list[i - 1].Length;
list[i].CopyTo(msg, c);
}
}
if (EventMessage != null)
{
tcount = 0;
System.Diagnostics.Trace.WriteLine("数据大于65400回发");
EventMessage(msg);
}
}
}
else
{
list.Add(byteMessage);
}
}
}//end while (ns != null && ns.DataAvailable)
}
}
catch (ObjectDisposedException odx)
{
_socket.Close();
_socket = null;
LogInfo.Instance.Log("socket chucuo"+odx.Message.ToString());
System.Diagnostics.Trace.WriteLine("BaseNetWork:ns.DataAvailable:--->:" + odx.Message);
_IsFinish = false;
}
//catch (Exception ex)
//{
// //_IsFinish = false;
// LogInfo.Instance.Log(ex.ToString());
// _socket.Close();
// _socket = null;
// if (Event_ConnectionState != null)
// Event_ConnectionState(false, ex.Message.ToString());
//}
}
}
/// <summary>
/// 检查Socket是否可用
/// </summary>
/// <param name="socket"></param>
/// <returns></returns>
public bool IsConnected(Socket socket)
{
try
{
if (socket.Connected && socket.Poll(0, SelectMode.SelectRead))
{
byte[] msg = new byte[1];
if (socket.Receive(msg, 0, 1, SocketFlags.Peek) != 0)
return true;
else
return false;
}
}
catch (Exception ex)
{
return false;
}
return socket.Connected;
}
当我客户端发送一条信息给服务端时,监听就一直开始循环,且与服务器连接上。我不间隔给服务器消息,服务器和客户端就不断开。。。。但是我隔10~20分钟以后操作:第一步:快速监听代码 socket.Receive(msg, 0, 1, SocketFlags.Peek) 是!= 0的,再次给服务器消息,代码就会抛出异常。(断开套接字连接后,只能通过异步方式再次重新连接,而且只能连接到不同的 EndPoint。在操作完成前,在将不会退出的线程上必须调用 BeginConnect。),我再次给服务器发送消息,又链接上了。。。。。
现在要解决长时间没有给服务器消息,一旦客户端发送消息,服务端马上回发消息。要思路即可。
用异步的不行,要其他方法,能自动链接的
------解决思路----------------------
异常是可以用 try 来捕获的
不管怎么整,连接都不是一定成功的,所以从逻辑上你要用代码来保证
比如设置一个重新尝试的次数,出现异常了自动重新连接 5 次
------解决思路----------------------
自动连接是客户端的事情,服务端不应该关系客户端是否断开了而不重新连接
总之你服务不死掉,有客户端连接进来,并发送消息,就可以做到立即回发消息
而客户端断开就断开了呗,客户端自己想办法重新连接,而不是服务端主动连接客户端
这个是我的客户端监听代码:
public void BeginListen(string ip, int _port)
{
_IsFinish = true;
_socket = SocekConnection();
IPAddress _ip;
_ip = IPAddress.Parse(ip);
IPEndPoint iep = new IPEndPoint(_ip, _port);
try
{
_socket.Connect(iep);
if (Event_ConnectionState != null)
Event_ConnectionState(true, "");
}
catch (Exception ex)
{
_socket.Close();
_socket = null;
LogInfo.Instance.Log(ex.ToString());
if (Event_ConnectionState != null)
Event_ConnectionState(false, "连接断开!"+ex.Message);
_IsFinish = false;
return;
}
ns = new NetworkStream(_socket, true);
List<byte[]> list = new List<byte[]>();
int tcount = 0;
while (_IsFinish)
{
if (!IsConnected(_socket))
{
if (Event_ConnectionState != null)
{
System.Diagnostics.Trace.WriteLine("服务器连接中断");
Event_ConnectionState(false, "服务器连接中断!");
_IsFinish = false;
return;
}
}
try
{
if (ns.CanRead)
{
_socket.NoDelay = true;
_socket.ReceiveBufferSize = 65406;
Thread.Sleep(50);
while (ns != null && ns.DataAvailable)
{
System.Diagnostics.Trace.WriteLine("============当前NetworkStream开始读取:===========");
byte[] RecFlagBuffer = new byte[2];
ns.Read(RecFlagBuffer, 0, 2);
int ContentSize = RecFlagBuffer[0] << 8 | RecFlagBuffer[1] << 0;
byte[] byteMessage = new byte[ContentSize];
int nscount = 0;
int receivcount = 0;
int first = 0;
int allcount = ContentSize;
int readcount = 0;
while ((nscount = ns.Read(byteMessage, first, allcount)) != 0)
{
System.Diagnostics.Trace.WriteLine("本次接收到的数据大小:" + nscount.ToString());
readcount++;
receivcount += nscount;
if (receivcount >= ContentSize)
break;
first = receivcount;
allcount = ContentSize - receivcount;
}
tcount++;
System.Diagnostics.Trace.WriteLine("本次接收次数:" + tcount.ToString() + " 实际大小:" + ContentSize.ToString() + " 接收到的大小:" + receivcount.ToString());
System.Diagnostics.Trace.WriteLine("byteMessage开始和结束字符:"+byteMessage[0].ToString() + " "+byteMessage[ContentSize-1].ToString());
if (tcount == 1 && ContentSize < 65400)
{
if (EventMessage != null)
{
tcount = 0;
System.Diagnostics.Trace.WriteLine("数据小于65400回发");
EventMessage(byteMessage);
}
}
else
{
if (ContentSize < 65400)
{
list.Add(byteMessage);
if (list.Count > 1)
{
int count = 0;
for (int i = 0; i < list.Count; i++)
{
count += list[i].Length;
}
byte[] msg = new byte[count];
int c = 0;
for (int i = 0; i < list.Count; i++)
{
if (i == 0)
{
list[i].CopyTo(msg, 0);
}
else
{
c += list[i - 1].Length;
list[i].CopyTo(msg, c);
}
}
if (EventMessage != null)
{
tcount = 0;
System.Diagnostics.Trace.WriteLine("数据大于65400回发");
EventMessage(msg);
}
}
}
else
{
list.Add(byteMessage);
}
}
}//end while (ns != null && ns.DataAvailable)
}
}
catch (ObjectDisposedException odx)
{
_socket.Close();
_socket = null;
LogInfo.Instance.Log("socket chucuo"+odx.Message.ToString());
System.Diagnostics.Trace.WriteLine("BaseNetWork:ns.DataAvailable:--->:" + odx.Message);
_IsFinish = false;
}
//catch (Exception ex)
//{
// //_IsFinish = false;
// LogInfo.Instance.Log(ex.ToString());
// _socket.Close();
// _socket = null;
// if (Event_ConnectionState != null)
// Event_ConnectionState(false, ex.Message.ToString());
//}
}
}
/// <summary>
/// 检查Socket是否可用
/// </summary>
/// <param name="socket"></param>
/// <returns></returns>
public bool IsConnected(Socket socket)
{
try
{
if (socket.Connected && socket.Poll(0, SelectMode.SelectRead))
{
byte[] msg = new byte[1];
if (socket.Receive(msg, 0, 1, SocketFlags.Peek) != 0)
return true;
else
return false;
}
}
catch (Exception ex)
{
return false;
}
return socket.Connected;
}
当我客户端发送一条信息给服务端时,监听就一直开始循环,且与服务器连接上。我不间隔给服务器消息,服务器和客户端就不断开。。。。但是我隔10~20分钟以后操作:第一步:快速监听代码 socket.Receive(msg, 0, 1, SocketFlags.Peek) 是!= 0的,再次给服务器消息,代码就会抛出异常。(断开套接字连接后,只能通过异步方式再次重新连接,而且只能连接到不同的 EndPoint。在操作完成前,在将不会退出的线程上必须调用 BeginConnect。),我再次给服务器发送消息,又链接上了。。。。。
现在要解决长时间没有给服务器消息,一旦客户端发送消息,服务端马上回发消息。要思路即可。
用异步的不行,要其他方法,能自动链接的
------解决思路----------------------
异常是可以用 try 来捕获的
不管怎么整,连接都不是一定成功的,所以从逻辑上你要用代码来保证
比如设置一个重新尝试的次数,出现异常了自动重新连接 5 次
------解决思路----------------------
自动连接是客户端的事情,服务端不应该关系客户端是否断开了而不重新连接
总之你服务不死掉,有客户端连接进来,并发送消息,就可以做到立即回发消息
而客户端断开就断开了呗,客户端自己想办法重新连接,而不是服务端主动连接客户端