在LAN中还是WAN中?
在WAN中,如果客户端跨网关,则服务器不能得到客户端的IP。
不然,可用 EndPoint ep = sock.RemoteEndPoint得到客户端的IP及端口。

解决方案 »

  1.   

    在mfc中,如果客户端断开,会触发服务器的onclose事件,可是在c#中,我没有找到,求助解决方法。
      

  2.   

    以下是我写的一个类.调用TcpServer2.StartListener()方法可以开始侦听.using System;
    using System.IO;
    using System.Net.Sockets;
    using System.Text;
    using System.Collections;
    using System.Threading;namespace ConsoleSocket
    {
    /// <summary>
    /// TcpServer2 的摘要说明。
    /// </summary>
    public class TcpServer2
    { public  enum MessageType
    {
    userAdd = 1,
    userRemove =2, } private  static  ArrayList ClientSockets  ;

    //代理回调
    public delegate void myMethodDelegate( byte[] byteMess,ClientInfo client );
    public delegate void myMethodProcessInput( );
    private static Thread ThreadReclaim ;
    private static Thread ThreadWeb ;
    private static bool _quit = false;
    private static TcpListener listener = null;
    private static TcpListener Weblistener = null;
    private static int m_webPort = 80;
    /// <summary>
    /// 在线用户集合
    /// </summary>
    public static ArrayList Cliects
    {
    get
    {
    return ClientSockets;
    }
    }
    /// <summary>
    /// 改变用户列表
    /// </summary>
    /// <param name="type">改类类型</param>
    /// <param name="client">操作用户</param>
    public static void ChangeUserList(MessageType type,ClientInfo client)
    {
    int iReturn = 0;
    if(type == MessageType.userAdd)
    {

    foreach (object obj in ClientSockets)
    {
    ((ClientInfo)obj).SendMess("add:" + client.Address[0] + ":" + client.NickName);
    }
    if(!ClientSockets.Contains(client))
    {
    iReturn =  ClientSockets.Add(client) ;
    }
    }
    else if(type == MessageType.userRemove )
    {
    ClientSockets.Remove(client) ;
    foreach (object obj in ClientSockets)
    {
    ((ClientInfo)obj).SendMess("remove:" + client.Address[0] + ":" + client.NickName); }
    }
    }
    public static void Close()
    {
    foreach (object obj in ClientSockets)
    {
    ((ClientInfo)obj).Close();
    }
    listener.Stop();
    ThreadReclaim.Join();
    ThreadWeb.Join();
    listener = null;

    } /// <summary>
    /// 开始侦听端口
    /// </summary>
    /// <param name="iPort">端口号</param>
    public static void StartListener(int iPort,int webPort,myMethodProcessInput procobj)
    {
    m_webPort = webPort;
    ThreadWeb = new Thread ( new ThreadStart(StartWebServer));
    ThreadReclaim = new Thread ( new ThreadStart(procobj));

    ThreadWeb.Start();
    listener = new TcpListener(iPort);

    Console.WriteLine("正在等待用户连接...."); 

    ThreadReclaim.Start();
    ClientSockets = new ArrayList() ;

    listener.Start(); while (!_quit)
    {
    Socket sockClient;
    try
    {
    sockClient = listener.AcceptSocket(); }
    catch
    {
    break;
    }
    if(sockClient.Connected)
    {
    myMethodDelegate myProc = new myMethodDelegate(TcpServer2.Process);

    lock( ClientSockets.SyncRoot ) 
    {
    ClientInfo client = new ClientInfo(sockClient,myProc);
    ChangeUserList(MessageType.userAdd, client);
    //int i =  ClientSockets.Add(client) ;
    Console.WriteLine("\n用户 {0} 已经连接到服务器.",client.Address[0]);  }
    } }
    ThreadReclaim.Join();
    ThreadWeb.Join(); }
      

  3.   

    public static void StartWebServer()
    {
    Weblistener = new TcpListener(m_webPort);
    Weblistener.Start();
    Console.WriteLine("\nWeb 服务已经启动"); 
    while (!_quit)
    {
    TcpClient sockClient;
    // try
    // {
    sockClient = Weblistener.AcceptTcpClient();// }
    // catch
    // {
    // break;
    // }
    myMethodDelegate myProc = new myMethodDelegate(TcpServer2.Process);

    NetworkStream networkStream = sockClient.GetStream();
    Console.WriteLine(sockClient.ReceiveBufferSize);
    byte[] getBytes = new Byte[sockClient.ReceiveBufferSize];
    networkStream.Read(getBytes,0,sockClient.ReceiveBufferSize); if(getBytes.Length>0)
    {
    string data  = Encoding.ASCII.GetString(getBytes);
    string[] comm  =  GetCommand(data);
    if(comm[0].ToUpper() == "SENDKEY")
    {
    SendMess(comm[1],comm[2]);
    }
    else if(comm[0].ToUpper() == "SENDIP")
    {
    SendMessFromIP(comm[1],comm[2]);
    }
    else if(comm[0].ToUpper() == "SENDNICK")
    {
    SendMessFromNick(comm[1],comm[2]);
    }

    }
    sockClient.Close();
    }
    }
    private static string[] GetCommand(string data)
    {
    string command = data.Substring(1,data.ToUpper().IndexOf("HTTP")-1);
    command = command.Substring(command.IndexOf("/")+1);

    return command.Split(new char[]{'?'}); }
    /// <summary>
    /// 通过已知昵称发送消息
    /// </summary>
    /// <param name="cNick">已知昵称</param>
    /// <param name="data">数据</param>
    /// <returns>成功返回发送成功数否则返回0</returns>
    public static int SendMessFromNick(string cNick,string data)
    {
    int iReturn = 0;
    foreach (object obj in ClientSockets)
    {
    if(((ClientInfo)obj).NickName==cNick)
    {
    ((ClientInfo)obj).SendMess(data);
    iReturn ++;
    //break;
    }
    }
    return iReturn;
    } /// <summary>
    /// 通过已知IP发送消息
    /// </summary>
    /// <param name="tIP">已知IP</param>
    /// <param name="data">数据</param>
    /// <returns>成功返回1否则返回0</returns>
    public static int SendMessFromIP(string tIP,string data)
    {
    int iReturn = 0;
    foreach (object obj in ClientSockets)
    {
    if(((ClientInfo)obj).Address[0] == tIP)
    {
    ((ClientInfo)obj).SendMess(data);
    iReturn = 1;
    break;
    }
    }
    return iReturn;
    } /// <summary>
    /// 通过已知IP发送消息
    /// </summary>
    /// <param name="tIP">已知用户关键字</param>
    /// <param name="data">数据</param>
    /// <returns>成功返回1否则返回0</returns>
    public static int SendMess(string key,string data)
    {
    int iReturn = 0;
    foreach (object obj in ClientSockets)
    {
    if(((ClientInfo)obj).Key  == key)
    {
    ((ClientInfo)obj).SendMess(data);
    iReturn = 1;
    break;
    }
    }
    return iReturn;
    }
    /// <summary>
    /// 检查并处理用户消息
    /// </summary>
    /// <param name="byteMess">用户消息</param>
    /// <param name="client">用户对象</param>
    private static void Process(byte[] byteMess,ClientInfo client)
    {
    if (byteMess !=null && byteMess.Length>0)
    {
    string data =  Encoding.ASCII.GetString(byteMess);
    if (data.ToUpper()=="[REMOTE]")
    {
    Console.WriteLine("\n用户 {0} 已经下线..",client.Address[0]); 
    ChangeUserList(MessageType.userRemove, client);
    }
    else
    {
    string [] actData = data.Split(new char[]{':'});
    if (actData[0].ToUpper() == "SAYALL")
    {
    foreach (object obj in ClientSockets)
    {
    ((ClientInfo)obj).SendMess(client.Address[0] + "," + client.NickName + ":" + actData[1]);
    }
    }
    else if(actData[0].ToUpper() =="RENAME")
    {
    if(actData[1]!=null && actData[1]!="")
    {
    client.NickName = actData[1];
    Console.WriteLine("\n用户  {0} 将昵称改为: {1}.\n",client.Address[0],actData[1]); 
    }
    }
    else if(actData[0].ToUpper() =="LOGIN")
    {
    if(actData[1]!=null && actData[1]!="")
    {
    bool ishavekey = false;
    ClientInfo selClient = null;
    int ilength = 0 ;
    int index =1;
    string sendUserList = "list:";
    client.NickName = actData[1];
    try
    {
    client.Key = actData[2];
    }
    catch
    {
    ishavekey = true;
    }
    if(!ishavekey)
    {
    Console.WriteLine("\n用户  {0} 的昵称为: {1}.\n",client.Address[0],actData[1]); 
    sendUserList += "<count>" +  ClientSockets.Count  + "</count>";
    foreach (object obj in ClientSockets)
    {
    if(ilength<2 | ((ClientInfo)obj).Key!=actData[2])
    {

    sendUserList += "<user" + index.ToString() + "><ip>" +  ((ClientInfo)obj).Address[0]  + "</ip><port>" +  ((ClientInfo)obj).Address[1]  + "</port><name>" +  ((ClientInfo)obj).NickName  + "</name></user" + index.ToString() + ">";

      

  4.   

    index ++;
    }
    else
    {
    ilength++;
    if(ilength>=2)
    {
    selClient = (ClientInfo)obj;
    ishavekey = true;
    break;
    }
    }
    }
    }
    if(ishavekey)
    {
    sendUserList = "invalidation key";
    if(sendUserList!=null)
    ClientSockets.Remove(sendUserList);
    }
    ((ClientInfo)client).SendMess(sendUserList); }
    }
    else
    {
    Console.WriteLine("\n用户  {0} 发送数据到服务器..\n",client.Address[0]); 
    Console.WriteLine("他说:" + data);
    }
    }
    }
    }
    }
    public class ClientInfo
    {
    private static string[] _address;
    private static string _nickname;
    private static string _key;
    private static Socket _sock;

    private static Thread _thread ;
    private static TcpServer2.myMethodDelegate _proc; public ClientInfo(Socket sock,TcpServer2.myMethodDelegate proc)
    {

    string _ip = sock.RemoteEndPoint.ToString();
    string[] address = _ip.Split(new char[]{':'});

    _address = address;
    _sock = sock;
    _proc = proc;
    _thread = new Thread ( new ThreadStart(Process) ) ;
    _thread.Start();
    }
    #region 类属性

    public string Key
    {
    get
    {
    return  _key;
    }
    set
    {
    _key = value;
    }
    }
    public string NickName 
    {
    get
    {
    return  _nickname ;
    }
    set
    {
    _nickname = value;
    }
    } public string[] Address
    {
    get
    {
    return _address;
    }

    } #endregion #region 类方法 public Socket getSocket()
    {
    return _sock;
    } //发送消息
    public int SendMess(string mess)
    {
    string data = "";
    byte[] sendBytes = Encoding.ASCII.GetBytes(data);
    int iReturn  = 0;
    try
    {
    iReturn = _sock.Send(sendBytes);
    }
    catch
    {
    data = "[remote]";
    sendBytes = Encoding.ASCII.GetBytes(data);

    _proc(sendBytes,this);
    }
    return iReturn;

    } public void Close()
    {
    _sock.Close();
    _thread.Join(); } private void Process()
    {
    bool _connected = _sock.Connected;
    string data = "ping\n";
    byte[] sendBytes = Encoding.ASCII.GetBytes(data);
    try
    {
    while (_connected)   
    {

    byte[] getBytes = new Byte[_sock.Available];
    // try
    // {
    _sock.Receive(getBytes);
    // }
    // catch
    // {
    // _connected = false;
    // }
    if(getBytes.Length>0)
    {
    _proc(getBytes,this);

    }
    // try
    // {
    _sock.Send(sendBytes);
    // }
    // catch
    // {
    // _connected = false;
    // }
    }
    }
    catch  ( SocketException ) 
    {
    data = "[remote]";
    sendBytes = Encoding.ASCII.GetBytes(data);

    _proc(sendBytes,this);

    }
    _thread.Join();
    }
    #endregion }}