最近要做一个局域网聊天的工具, 有很多不懂, 打扰了哈~~~
      1.关于登陆的问题。客户端通过输入账号密码(我用了个类CUser来保存这2个字符串), 验证是否有此账号, 有, 才跳转到主界面。那么, 要怎样实现发送到服务器端, 服务器再返回验证成功与否的信息咧?(PS:端口已定,客户端已知服务器的IP, 服务器却不知道客户端的IP)我希望用TCPCLIENT来做, 因为因为感觉UDP太不安全了哈~~
      2。客户端1退出的话, 服务器能够通知其他客户端退出信息, 这个又怎样实现咧?
      

解决方案 »

  1.   

    orz, 那我自己也顶一下, 等高手
      

  2.   

    WebService可以满足你的要求
    使用SOCKET,看下MSDN。UDP,和TCP区别不是安全性,
    他们区别是面向连接和非面向连接
    TCP保证数据传输的可靠性
      

  3.   

    你需要了解的相关知识有 IOCP, 多线程, TCP, Winsock
      

  4.   

    采用UDP和TCP协议
    通过socket和多线程机制,服务器端监听端口获取信息,要使用·UDP广播
    可看看飞鸽传书和MYQQ
    http://topic.csdn.net/u/20080623/08/4bbd2475-45f1-42e3-a613-16b094759ade.html?62697
    http://topic.csdn.net/u/20090122/01/47c5db17-13be-4be8-93e9-05f56a196264.html
      

  5.   

    使用套接字Socket ,从TCP/IP模型协议的逻辑面上说,可以分为三个层次: 请求\响应层 ,应用协议层,传输层。WebRequst\WebResponse代表了请求\响应层,支持Http,Tcp,Udp类组成的应用协议层,Socket类位于传输层。在这个结构的最底层。当请求\响应层 ,应用协议层不能满足需求时,SOCKEt可以大显神威。msdn上有很多socket的成员,方法等。
      

  6.   

    其实就是socket的东西。你这两个问题用socket都能解决。
    你的第一个问题可以直接连接到服务器的数据库对比用户名和密码。这个就简单了。
    第一个问题就是socket了,用户退出可以在客户端程序处罚一个事件。而事件触发后,可以写代码发送消息给服务器告之退出了,服务器接受后,分析这个用户的好友,然后再发给对应的用户
      

  7.   

    给你一个我项目的片段好了
    接收到连接请求后放入活动IP队列然后回复客户端        #region void AcceptLink() // 接受请求线程体
            /// <summary>
            /// 接受请求线程体
            /// </summary>
            void AcceptLink()
            {
                Listener.Start();
                while (!ThreadStop)
                {
                    TcpClient Client = null;
                    NetworkStream Stream = null;
                    Byte[] ReadBytes = new Byte[8];
                    Byte[] WriteBytes = new Byte[2];
                    try
                    {
                        Client = Listener.AcceptTcpClient();
                        IPAddress ClientIPAddress = ((IPEndPoint)Client.Client.RemoteEndPoint).Address;
                        int AcceptClientIPAddressIndex = IPAddresses.IndexOf(ClientIPAddress);
                        Stream = Client.GetStream();
                        Stream.Read(ReadBytes, 0, 8);
                        String Command = Encoding.Default.GetString(ReadBytes);
                        if (AcceptClientIPAddressIndex == -1 && Command == "A0650001") // 固化 连接
                        {
                            WriteBytes[0] = 48;
                            WriteBytes[1] = 49;
                            Stream.Write(WriteBytes, 0, 2);
                            IPAddresses.Add(ClientIPAddress); // 完全成功后生效
                        }
                        else if (AcceptClientIPAddressIndex >= 0 && Command == "A0650002") // 固化 服务关闭
                        {
                            IPAddresses.RemoveAt(AcceptClientIPAddressIndex); // 立即失效
                            WriteBytes[0] = 48;
                            WriteBytes[1] = 49;
                            Stream.Write(WriteBytes, 0, 2);
                        }
                        else if (AcceptClientIPAddressIndex == -1 && Command == "A0650003") // 固化 连接测试
                        {
                            WriteBytes[0] = 48;
                            WriteBytes[1] = 49;
                            Stream.Write(WriteBytes, 0, 2);
                            IPAddresses.Add(ClientIPAddress); // 完全成功后生效
                        }
                        else if (AcceptClientIPAddressIndex >= 0 && Command == "0000000A") // 固化 服务开始
                        {
                            System.ServiceProcess.ServiceController sc = new ServiceController();
                            sc.ServiceName = Consts.SERVICE_NAME;
                            sc.Start();
                            sc.WaitForStatus(ServiceControllerStatus.Running);
                            WriteBytes[0] = 48;
                            WriteBytes[1] = 49;
                            Stream.Write(WriteBytes, 0, 2);
                        }
                        else if (AcceptClientIPAddressIndex >= 0 && Command == "0000000B") // 固化 服务停止
                        {
                            System.ServiceProcess.ServiceController sc = new ServiceController();
                            sc.ServiceName = Consts.SERVICE_NAME;
                            sc.Stop();
                            sc.WaitForStatus(ServiceControllerStatus.Stopped);
                            WriteBytes[0] = 48;
                            WriteBytes[1] = 49;
                            Stream.Write(WriteBytes, 0, 2);
                        }
                        else if (AcceptClientIPAddressIndex >= 0 && Command == "0000000C") // 固化 获取服务状态
                        {
                            System.ServiceProcess.ServiceController sc = new ServiceController();
                            sc.ServiceName = Consts.SERVICE_NAME;
                            if (sc.Status == ServiceControllerStatus.StopPending)
                            {
                                WriteBytes[0] = 48;
                                WriteBytes[1] = 49;
                            }
                            else if (sc.Status == ServiceControllerStatus.Stopped)
                            {
                                WriteBytes[0] = 48;
                                WriteBytes[1] = 50;
                            }
                            else if (sc.Status == ServiceControllerStatus.StartPending)
                            {
                                WriteBytes[0] = 48;
                                WriteBytes[1] = 51;
                            }
                            else if (sc.Status == ServiceControllerStatus.Running)
                            {
                                WriteBytes[0] = 48;
                                WriteBytes[1] = 52;
                            }
                            Stream.Write(WriteBytes, 0, 2);
                        }
                        else if (AcceptClientIPAddressIndex >= 0 && Command == "0000000D") // 固化 本地化分析
                        {
                            WriteBytes[0] = 48;
                            WriteBytes[1] = 48;
                            Stream.Write(WriteBytes, 0, 2);
                            Byte[] ReadInfoBytes = new Byte[5000000];
                            Stream.Read(ReadInfoBytes, 0,5000000);
                            MemoryStream MS = new MemoryStream(ReadInfoBytes);
                            IFormatter BF = new BinaryFormatter();
                            Params StartupParams = (Params)BF.Deserialize(MS);
                            ProcessEntry PE = new ProcessEntry();
                            PE.Main(StartupParams);
                            MS = new MemoryStream();
                            BF.Serialize(MS, StartupParams);
                            Byte[] WriteInfoBytes = MS.ToArray();
                            Stream.Write(WriteInfoBytes, 0, WriteInfoBytes.Length);
                        }
                        Stream.Close();
                        Stream = null;
                    }
                    catch (Exception e)
                    {
                        try
                        {
                            EventLog.WriteEntry(Consts.SERVICE_CONTROL_NAME, e.Message, EventLogEntryType.Information);
                            if (Client != null && Stream != null)
                            {
                                WriteBytes[0] = 49;
                                WriteBytes[1] = 49;
                                Stream.Write(WriteBytes, 0, 2);
                            }
                        }
                        catch
                        {
                            // 如果返回错误代码也发生了异常则忽略异常,以保证服务不会因网络问题等而导致崩溃后停止
                        }
                    }
                    finally
                    {
                        try
                        {
                            if (Stream != null)
                            {
                                Stream.Close();
                                Stream = null;
                            }
                            if (Client != null)
                            {
                                Client.Close();
                                Client = null;
                            }
                        }
                        catch
                        {
                            // 如果关闭连接也发生了异常则忽略异常,以保证服务不会因网络问题等而导致崩溃后停止
                        }
                    }
                }
            }
            #endregion
      

  8.   

    服务器:
    监听TcpListener
    接受挂起的客户端
    建立网络流
    读取网络流
    验证
    写入网络流客户端:
    连接服务器
    建立网络流
    验证信息写入网络流
    读取网络流(返回的标识)
      

  9.   

    使用webService、socket
    给你一些例子参考一下吧!
    http://www.bbs180.com/topictag-29.aspx
    UDP和tcp 两种方法实现的socket通讯示例程序,VC6 vc++  supper168 2009.09.15 07:51  1 317 2009.09.15 13:44 
    by leo  
    关于C#中关于串口的监听 c#  水墨坊 2009.03.21 21:47  3 976 2009.09.14 09:09 
    by 水墨坊  
    网络应用编程C#聊天程,VS2005 c#  水墨坊 2009.05.19 22:38  2 1090 2009.07.01 19:10 
    by liyoubaidu  
    Monitor UDP Network Package监听指定端口发送的UDP信息 c#  水墨坊 2009.06.10 09:08  0 754 2009.06.10 09:08 
    by 水墨坊  
    Java Socket的单客户服务器通信JDK1.4 J2EE  水墨坊 2009.05.31 11:08  0 984 2009.05.31 11:08 
    by 水墨坊  
    Socket与拔掉网线 c#  supper168 2009.04.26 09:57  0 822 2009.04.26 09:57 
    by supper168  
    如何优雅地关闭一个Socket c#  supper168 2009.04.26 09:57  0 823 2009.04.26 09:57 
    by supper168  
    C#在Socket中用Acceptex方法加速连接 c#  supper168 2009.04.26 09:56  0 854 2009.04.26 09:56 
    by supper168  
    在C#中实现Socket端口复用 c#  supper168 2009.04.26 09:55  0 747 2009.04.26 09:55 
    by supper168  
    C# Socket连接请求超时机制 c#  supper168 2009.04.26 09:54  0 732 2009.04.26 09:54 
    by supper168  
    关于socket异步的问题 c#  supper168 2009.04.21 14:30  0 775 2009.04.21 14:30 
    by supper168  
    网络socket编程指南 c#  azong1988 2009.04.08 19:48  2 1002 2009.04.15 21:35 
    by supper168  
      

  10.   

    谢谢谢谢~~~只是SOCKET得东西哈?我网络编程方面不熟悉~~~
      

  11.   

    客户端发往服务器的消息采用TCP协议,然后服务器通过基于UDP的多播协议把消息发往每个已连接的客户端。
    类似的通信过程可能是这样:登录:
    客护端请求:HELLO:登陆信息(用户名和密码)
    服务器端:先验证,成功则响应 HELLO:聊天室信息(同时服务器端通过UDP的多播协议把用户名发送给所有已连接的客户)聊天:
    客户端请求:SAY:用户名:消息
    服务器端应答:OK(同时服务器通过UDP的多播协议把"用户名:消息"发送给所有已连接客户)离开:
    客户端请求:BYE:用户名
    服务器端:服务器通过UDP多播协议把"用户名已经离开"发送给已连接客户
    所谓UDP的多播协议就是利用了UDP的广播功能,把一组用户集合起来,赋予一个特殊的ip地址(224.0.0.0~239.255.255.255)和端口,这样其他用户只要知道这一ip和端口就能与组中的其他成员同时通信