鸟语天空
TcpListener
post by:追风剑情 2015-10-12 13:59


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
using System.Net;
using System.Net.Sockets;

namespace TestServer
{
    class Program
    {
        static List<ServerPlayer> playerList = new List<ServerPlayer>();

        static void Main(string[] args)
        {
            TcpListener server=null;   
            try
            {
              Int32 port = 13000;
              IPAddress localAddr = IPAddress.Parse("127.0.0.1");

              server = new TcpListener(localAddr, port);
              server.Start();

              Console.WriteLine("Server started");

              while(true) 
              {
                Console.Write("Waiting for a connection... ");

                TcpClient client = server.AcceptTcpClient();      
                Console.WriteLine("Connected!");
                playerList.Add( new ServerPlayer(client) );

                ThreadPoolInfo();
              }
            }
            catch(SocketException e)
            {
              Console.WriteLine("SocketException: {0}", e);
            }
            finally
            {
               server.Stop();
            }

            Console.WriteLine("\nHit enter to continue...");
            Console.Read();  
        }

        //显示线程池现状
        static void ThreadPoolInfo()
        {
            int a, b;
            ThreadPool.GetAvailableThreads(out a, out b);
            string message = string.Format("CurrentThreadId is : {0}\n" +
                "WorkerThreads is : {1}\nCompletionPortThreads is : {2}\n",
                 Thread.CurrentThread.ManagedThreadId, a.ToString(), b.ToString());

            Console.WriteLine(message);
        }
    }
}

public class ServerPlayer
{
    private TcpClient tcpClient;
    private byte[] receiveBuffer;
    private string clientEndPoint;

    public ServerPlayer(TcpClient tcpClient)
    {
        this.tcpClient = tcpClient;
        receiveBuffer = new byte[tcpClient.ReceiveBufferSize];
        //显示客户端信息
        clientEndPoint = tcpClient.Client.RemoteEndPoint.ToString();
        Console.WriteLine("Client connected : " + clientEndPoint);

        NetworkStream stream = tcpClient.GetStream();
        stream.BeginRead(receiveBuffer, 0, receiveBuffer.Length, new AsyncCallback(ReadCallback), stream);
    }

    void ReadCallback(IAsyncResult result)
    {
        NetworkStream stream = (NetworkStream)result.AsyncState;
        int length = stream.EndRead(result);
        if (length < 1)//TCP中断了
        {
            Console.WriteLine("client disconnected : " + clientEndPoint);
            return;
        }

        //显示接收信息
        string message = Encoding.UTF8.GetString(receiveBuffer, 0, length);
        Console.WriteLine("Message: " + message);

        //向客户端返回ok
        byte[] msg = System.Text.Encoding.UTF8.GetBytes("ok");
        stream.Write(msg, 0, msg.Length);

        stream.BeginRead(receiveBuffer, 0, receiveBuffer.Length, new AsyncCallback(ReadCallback), stream);
    }
}


运行效果

tttt.png

示例二:增加大厅功能,实现聊天室

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
using System.Net;
using System.Net.Sockets;

namespace TestServer
{
    class Program
    {
        static ServerLobby defaultLobby;

        static void Main(string[] args)
        {
            TcpListener server = null;
            try
            {
                Int32 port = 13000;
                IPAddress localAddr = IPAddress.Parse("127.0.0.1");

                server = new TcpListener(localAddr, port);
                server.Start();

                Console.WriteLine("Server started");

                //建立默认大厅
                defaultLobby = new ServerLobby();

                while (true)
                {
                    Console.WriteLine("Waiting for a connection... ");

                    TcpClient client = server.AcceptTcpClient();
                    Console.WriteLine("Connected!");

                    //进入大厅
                    ServerPlayer player = new ServerPlayer(client);
                    defaultLobby.OnEnterServerPlayer(player);

                    ThreadPoolInfo();
                }
            }
            catch (SocketException e)
            {
                Console.WriteLine("SocketException: {0}", e);
            }
            finally
            {
                server.Stop();
            }

            Console.WriteLine("\nHit enter to continue...");
            Console.Read();
        }

        //显示线程池现状
        static void ThreadPoolInfo()
        {
            int a, b;
            ThreadPool.GetAvailableThreads(out a, out b);
            string message = string.Format("CurrentThreadId is : {0}\n" +
                "WorkerThreads is : {1}\nCompletionPortThreads is : {2}\n",
                 Thread.CurrentThread.ManagedThreadId, a.ToString(), b.ToString());

            Console.WriteLine(message);
        }
    }
}

// 大厅,管理所有ServerPlayer
public class ServerLobby
{
    private List<ServerPlayer> playerList = new List<ServerPlayer>();

    // 有玩家进入大厅
    public void OnEnterServerPlayer(ServerPlayer player)
    {
        player.OnEnterLobby(this);
        playerList.Add(player);
    }

    // 有玩家离开大厅
    public void OnLeaveServerPlayer(ServerPlayer player)
    {
        playerList.Remove(player);
        player.OnLeaveLobby();
    }

    // 向大厅中的所有玩家广播消息
    public void BroadcastMessage(string msg)
    {
        for (int i=0; i<playerList.Count; i++)
        {
            if (playerList[i] == null)
                continue;
            playerList[i].SendMessage(msg);
        }
    }
}

public class ServerPlayer
{
    private TcpClient tcpClient;
    private NetworkStream stream;
    private byte[] receiveBuffer;
    private string clientEndPoint;
    private AsyncCallback mAsyncCallback;
    private ServerLobby mServerLobby;
    private string clientIP;

    public string IP { get { return clientIP; } }

    public ServerPlayer(TcpClient tcpClient)
    {
        this.tcpClient = tcpClient;
        receiveBuffer = new byte[tcpClient.ReceiveBufferSize];
        //显示客户端信息
        clientEndPoint = tcpClient.Client.RemoteEndPoint.ToString();
        clientIP = clientEndPoint;
        Console.WriteLine("Client connected : " + clientEndPoint);

        stream = tcpClient.GetStream();
        mAsyncCallback = new AsyncCallback(ReadCallback);
        stream.BeginRead(receiveBuffer, 0, receiveBuffer.Length, mAsyncCallback, stream);
    }

    void ReadCallback(IAsyncResult result)
    {
        NetworkStream stream = (NetworkStream)result.AsyncState;
        int length = stream.EndRead(result);
        if (length < 1)//TCP中断了
        {
            Console.WriteLine("client disconnected : " + clientEndPoint);
            //离开大厅
            if (mServerLobby != null)
                mServerLobby.OnLeaveServerPlayer(this);
            return;
        }

        //显示接收信息
        string message = Encoding.UTF8.GetString(receiveBuffer, 0, length);
        Console.WriteLine("Message: " + message);

        //向大厅中的所有玩家同步消息
        mServerLobby.BroadcastMessage("sync: " + message.Trim() + "\r\n");

        stream.BeginRead(receiveBuffer, 0, receiveBuffer.Length, mAsyncCallback, stream);
    }

    // 发消息
    public void SendMessage(string msg)
    {
        if (!tcpClient.Connected)
            return;

        byte[] bytes = System.Text.Encoding.UTF8.GetBytes(msg);
        stream.Write(bytes, 0, msg.Length);
    }

    // 本玩家进入大厅触发
    public void OnEnterLobby(ServerLobby lobby)
    {
        mServerLobby = lobby;
        //通知大厅中的其他玩家
        mServerLobby.BroadcastMessage(IP + " enter lobby\r\n");
    }

    // 本玩家离开大厅触发
    public void OnLeaveLobby()
    {
        //通知大厅中的其他玩家
        mServerLobby.BroadcastMessage(IP + " leave lobby\r\n");
        mServerLobby = null;
    }
}

运行测试

11111.png

评论:
发表评论:
昵称

邮件地址 (选填)

个人主页 (选填)

内容