由于日常使用中经常需要调试tcp客户端程序,因此写了一个简单的tcpserver,能处理多客户端,接收它们的消息,同时对所有客户端发出消息。
为了使得防火墙不跳出警告,只实现对本地3000端口的监听,无法连接远程客户端。
代码如下:
class Listener
{
TcpListener listener;
List<TcpClient> clients = new List<TcpClient>();
public Listener()
{
listener = new TcpListener(new IPEndPoint(IPAddress.Loopback, 3000));
}
public void Run()
{
System.Threading.ThreadPool.QueueUserWorkItem(x => send_message());
Console.WriteLine("begin to get sockets...");
listener.Start();
while (true)
{
TcpClient client = listener.AcceptTcpClient();
Console.WriteLine("get connect from:\t"+client.Client.RemoteEndPoint);
clients.Add(client);
begin_read(client, new byte[1024]);
}
}
void send_message()
{
while (true)
{
string msg = Console.ReadLine();
byte[] data = Encoding.Default.GetBytes(msg + "\r\n");
Console.WriteLine("send:\t|" + msg + "|");
foreach (var item in clients)
{
item.GetStream().Write(data, 0, data.Length);
}
}
}
void begin_read(TcpClient client, byte[] buffer)
{
client.GetStream().BeginRead(
buffer, 0, buffer.Length,
x => end_read(x, client, buffer),
null);
}
void end_read(IAsyncResult ar, TcpClient client, byte[] buffer)
{
try
{
int count = client.GetStream().EndRead(ar);
if (count == 0)
{
Console.WriteLine("socket is closed.");
handle_err(new SocketException((int)SocketError.Disconnecting), client);
return;
}
Console.WriteLine("read:\t" + Encoding.Default.GetString(buffer, 0, count));
begin_read(client, buffer);
}
catch (Exception e)
{
handle_err(e, client);
}
}
void handle_err(Exception e, TcpClient client)
{
client.Close();
clients.Remove(client);
Console.WriteLine(e.Message);
}
这个程序主要是用于tcp程序的测试,不考虑效率问题(对效率有严格要求的地方一般就用C++写了,.net垃圾回收效率好像还是不行),不过这个服务器数据收发采用的是异步架构,效率应该不错。