借朋友的号给大家散分
namespace Proxy_Server
{
public class Listener
{
/// <summary>
/// 启动监听,轮询监听客户机请求并将客户端套接字存入转发表
/// </summary>
public void StartProxy()
{
......................................
.....................
while (true)
{
Thread.Sleep(5);
Socket newClient = _tcpl.AcceptSocket();//本地TcpListener 接受新的请求 IPAddress remote_ip = ((System.Net.IPEndPoint)newClient.RemoteEndPoint).Address;//获取客户连接IP
int remote_port = ((System.Net.IPEndPoint)newClient.RemoteEndPoint).Port;
string ClientId = remote_ip.ToString() + ":" + remote_port;
if (_transmit_tb.Count != 0 && _transmit_tb.ContainsKey(ClientId))
{
Console.WriteLine("客户端IP:" + ClientId + "已存在,踢出该连接..\n");
Console.WriteLine();
continue;
}
else
{
Connect(ClientId);//创建代理与游戏服务器连接
if (_tcpc == null)
{
Console.WriteLine("与游戏服务器连接失败...\n");
Console.WriteLine();
_tcpc.Close();
continue;
}
//将连接保存到哈希表
// NetworkStream netstream = _tcpc.GetStream();
_receive_tb.Add(ClientId, _tcpc);
_transmit_tb.Add(ClientId, newClient); //-----------------------
string svrlog = string.Format("新客户端 {0} 在 {1} 已代理... 当前在线人数: {2}\r\n\r\n", ClientId, DateTime.Now, _transmit_tb.Count);
Console.WriteLine(svrlog);
Console.WriteLine();
//------------------------
//创建新线程服务
Thread clientThreadSend = new Thread(new ParameterizedThreadStart(ThreadFuncSend));
clientThreadSend.Start(ClientId);
Thread clientThreadRead = new Thread(new ParameterizedThreadStart(ThreadFuncRead));
clientThreadRead.Start(ClientId);
}
}
} #endregion /// <summary>
/// 创建于游戏服务器连接
/// </summary>
/// <param name="remote_ip"></param>
/// <returns></returns>
public TcpClient Connect(string remote_ip)
{
try
{
IPAddress _ipAddr = IPAddress.Parse(SrvInfo.gamesrvip);
int _Port = int.Parse(SrvInfo.gamesrvport);
_tcpc = new TcpClient();
_tcpc.Connect(_ipAddr, _Port);//连接到服务
string svrlog = string.Format("服务器新建立{0}与{1}的连接...\n", remote_ip.ToString(), _ipAddr.ToString());
Console.WriteLine(svrlog);
Console.WriteLine();
}
catch (Exception)
{
return null;
}
return _tcpc;
} /// <summary>
/// 从客户端获取数据发送给游戏服务器
/// </summary>
/// <param name="obj"></param>
public void ThreadFuncSend(object obj)
{
//通过转发表得到当前用户套接字
Socket clientSkt = _transmit_tb[obj] as Socket;
TcpClient myclient = _receive_tb[obj] as TcpClient;
NetworkStream netstream = myclient.GetStream();
// NetworkStream netstream = _receive_tb[obj] as NetworkStream; byte[] buffer = new byte[_maxPacket];
int recvlen = 0;
while (true)
{
try
{
recvlen = clientSkt.Receive(buffer); //从客户端获取数据
if (recvlen > 0)
{
netstream.Write(buffer, 0, recvlen); //发送给游戏服务器
netstream.Flush();
}
buffer = new byte[_maxPacket]; //清空
}
catch (SocketException ex)
{
WriteData.WriteLine(ex.Message);
Close(clientSkt, netstream, myclient, obj);
string svrlog = string.Format("Send - IP:{0} 在 {1} 断开与代理连接! 当前连接数:{2}\r\n\r\n", obj, DateTime.Now, _transmit_tb.Count);
Console.WriteLine(svrlog);
Console.WriteLine();
Thread.CurrentThread.Abort();
}
finally { }
//打印客户发送的异常数据
if (recvlen > 1024 || recvlen < 10)
{
if (recvlen > 0)
{
string str = string.Empty;
for (int i = 0; i < recvlen; i++)
{
str += string.Format("{0:X}", buffer[i]);
}
WriteData.WriteLine(obj + ": " + str);
}
} Thread.Sleep(5);
}
} /// <summary>
/// 从游戏服务器读取数据发送给客户端
/// </summary>
/// <param name="obj"></param>
public void ThreadFuncRead(object obj)
{
//通过转发表得到当前用户套接字
Socket clientSkt = _transmit_tb[obj] as Socket;
TcpClient myclient = _receive_tb[obj] as TcpClient;
NetworkStream netstream = myclient.GetStream();
//NetworkStream netstream = _receive_tb[obj] as NetworkStream; byte[] buffer = new byte[_maxPacket];
int recvlen = 0;
while (true)
{
try
{ recvlen = netstream.Read(buffer, 0, buffer.Length); //从主服务器获取数据
if (recvlen > 0)
{
clientSkt.Send(buffer, recvlen, SocketFlags.None);//发送给客户端
}
buffer = new byte[_maxPacket];//清空
}
catch (SocketException ex)
{
WriteData.WriteLine(ex.Message);
Close(clientSkt, netstream, myclient, obj);
string svrlog = string.Format("Read - 客户端:{0}的代理与游戏服务器断开! {1} \r\n\r\n", obj, DateTime.Now);
Console.WriteLine(svrlog);
Console.WriteLine();
Thread.CurrentThread.Abort();
}
finally { }
Thread.Sleep(5);
}
} /// <summary>
/// 释放
/// </summary>
public void Close(Socket clientSkt, NetworkStream netstream, TcpClient myclient, object obj)
{
//clientSkt.Shutdown(SocketShutdown.Both);
//myclient.Client.Shutdown(SocketShutdown.Both);
if (clientSkt != null)
{
clientSkt.Close();
}
if (netstream != null)
{
netstream.Close();
}
if (myclient != null)
{
myclient.Close();
myclient.Client.Close();
}
_transmit_tb.Remove(obj); //从哈希表移除
_receive_tb.Remove(obj);
} }
}现在的问题是不稳定,每个客户端连接,我开两个线程为其服务,一个线程负责接收客户端信息发送给游戏服务端,另外一个线程负责接收游戏服务器数据发送给客户端!现在释放有个问题,如果有一个方法释放了Socket和cpClient,另一个方法的Read或Receive就会报错!还有很多特殊情况等!
c#的socket是不安全的,请高人优化下,程序如何修改才能稳定!
namespace Proxy_Server
{
public class Listener
{
/// <summary>
/// 启动监听,轮询监听客户机请求并将客户端套接字存入转发表
/// </summary>
public void StartProxy()
{
......................................
.....................
while (true)
{
Thread.Sleep(5);
Socket newClient = _tcpl.AcceptSocket();//本地TcpListener 接受新的请求 IPAddress remote_ip = ((System.Net.IPEndPoint)newClient.RemoteEndPoint).Address;//获取客户连接IP
int remote_port = ((System.Net.IPEndPoint)newClient.RemoteEndPoint).Port;
string ClientId = remote_ip.ToString() + ":" + remote_port;
if (_transmit_tb.Count != 0 && _transmit_tb.ContainsKey(ClientId))
{
Console.WriteLine("客户端IP:" + ClientId + "已存在,踢出该连接..\n");
Console.WriteLine();
continue;
}
else
{
Connect(ClientId);//创建代理与游戏服务器连接
if (_tcpc == null)
{
Console.WriteLine("与游戏服务器连接失败...\n");
Console.WriteLine();
_tcpc.Close();
continue;
}
//将连接保存到哈希表
// NetworkStream netstream = _tcpc.GetStream();
_receive_tb.Add(ClientId, _tcpc);
_transmit_tb.Add(ClientId, newClient); //-----------------------
string svrlog = string.Format("新客户端 {0} 在 {1} 已代理... 当前在线人数: {2}\r\n\r\n", ClientId, DateTime.Now, _transmit_tb.Count);
Console.WriteLine(svrlog);
Console.WriteLine();
//------------------------
//创建新线程服务
Thread clientThreadSend = new Thread(new ParameterizedThreadStart(ThreadFuncSend));
clientThreadSend.Start(ClientId);
Thread clientThreadRead = new Thread(new ParameterizedThreadStart(ThreadFuncRead));
clientThreadRead.Start(ClientId);
}
}
} #endregion /// <summary>
/// 创建于游戏服务器连接
/// </summary>
/// <param name="remote_ip"></param>
/// <returns></returns>
public TcpClient Connect(string remote_ip)
{
try
{
IPAddress _ipAddr = IPAddress.Parse(SrvInfo.gamesrvip);
int _Port = int.Parse(SrvInfo.gamesrvport);
_tcpc = new TcpClient();
_tcpc.Connect(_ipAddr, _Port);//连接到服务
string svrlog = string.Format("服务器新建立{0}与{1}的连接...\n", remote_ip.ToString(), _ipAddr.ToString());
Console.WriteLine(svrlog);
Console.WriteLine();
}
catch (Exception)
{
return null;
}
return _tcpc;
} /// <summary>
/// 从客户端获取数据发送给游戏服务器
/// </summary>
/// <param name="obj"></param>
public void ThreadFuncSend(object obj)
{
//通过转发表得到当前用户套接字
Socket clientSkt = _transmit_tb[obj] as Socket;
TcpClient myclient = _receive_tb[obj] as TcpClient;
NetworkStream netstream = myclient.GetStream();
// NetworkStream netstream = _receive_tb[obj] as NetworkStream; byte[] buffer = new byte[_maxPacket];
int recvlen = 0;
while (true)
{
try
{
recvlen = clientSkt.Receive(buffer); //从客户端获取数据
if (recvlen > 0)
{
netstream.Write(buffer, 0, recvlen); //发送给游戏服务器
netstream.Flush();
}
buffer = new byte[_maxPacket]; //清空
}
catch (SocketException ex)
{
WriteData.WriteLine(ex.Message);
Close(clientSkt, netstream, myclient, obj);
string svrlog = string.Format("Send - IP:{0} 在 {1} 断开与代理连接! 当前连接数:{2}\r\n\r\n", obj, DateTime.Now, _transmit_tb.Count);
Console.WriteLine(svrlog);
Console.WriteLine();
Thread.CurrentThread.Abort();
}
finally { }
//打印客户发送的异常数据
if (recvlen > 1024 || recvlen < 10)
{
if (recvlen > 0)
{
string str = string.Empty;
for (int i = 0; i < recvlen; i++)
{
str += string.Format("{0:X}", buffer[i]);
}
WriteData.WriteLine(obj + ": " + str);
}
} Thread.Sleep(5);
}
} /// <summary>
/// 从游戏服务器读取数据发送给客户端
/// </summary>
/// <param name="obj"></param>
public void ThreadFuncRead(object obj)
{
//通过转发表得到当前用户套接字
Socket clientSkt = _transmit_tb[obj] as Socket;
TcpClient myclient = _receive_tb[obj] as TcpClient;
NetworkStream netstream = myclient.GetStream();
//NetworkStream netstream = _receive_tb[obj] as NetworkStream; byte[] buffer = new byte[_maxPacket];
int recvlen = 0;
while (true)
{
try
{ recvlen = netstream.Read(buffer, 0, buffer.Length); //从主服务器获取数据
if (recvlen > 0)
{
clientSkt.Send(buffer, recvlen, SocketFlags.None);//发送给客户端
}
buffer = new byte[_maxPacket];//清空
}
catch (SocketException ex)
{
WriteData.WriteLine(ex.Message);
Close(clientSkt, netstream, myclient, obj);
string svrlog = string.Format("Read - 客户端:{0}的代理与游戏服务器断开! {1} \r\n\r\n", obj, DateTime.Now);
Console.WriteLine(svrlog);
Console.WriteLine();
Thread.CurrentThread.Abort();
}
finally { }
Thread.Sleep(5);
}
} /// <summary>
/// 释放
/// </summary>
public void Close(Socket clientSkt, NetworkStream netstream, TcpClient myclient, object obj)
{
//clientSkt.Shutdown(SocketShutdown.Both);
//myclient.Client.Shutdown(SocketShutdown.Both);
if (clientSkt != null)
{
clientSkt.Close();
}
if (netstream != null)
{
netstream.Close();
}
if (myclient != null)
{
myclient.Close();
myclient.Client.Close();
}
_transmit_tb.Remove(obj); //从哈希表移除
_receive_tb.Remove(obj);
} }
}现在的问题是不稳定,每个客户端连接,我开两个线程为其服务,一个线程负责接收客户端信息发送给游戏服务端,另外一个线程负责接收游戏服务器数据发送给客户端!现在释放有个问题,如果有一个方法释放了Socket和cpClient,另一个方法的Read或Receive就会报错!还有很多特殊情况等!
c#的socket是不安全的,请高人优化下,程序如何修改才能稳定!
我发的是关键位置的!
recvlen = clientSkt.Receive(buffer); //从客户端获取数据
recvlen = netstream.Read(buffer, 0, buffer.Length); //从主服务器获取数据
这两个位置不稳定不管我释放不释放都不稳定!