公司叫C#写个类似qq聊天的软件啊,用socket写该怎么设计啊,,
用tcp还是udp啊,我登录 把登录包发送给数据库 自己的客户端怎么得到好友列表啊,,,
得到好友列表怎么单独聊啊 ,
希望大家给个思路啊 ,,,,我现在下不了手啊

解决方案 »

  1.   

    udp要丢包代码
    网上找点源码来看看。
      

  2.   

    肯定用tcp了呗
    udp的话不用请求了我以前写过,可是代码有点多了,发的话太麻烦了,java的 asp的都有
      

  3.   

    web 的我建议用 tcp 吧.给你一点小的思路.首先  你需要一个服务器,嘿嘿,服务器有了 当然客户端就会有了服务器用Socket 写,给你弄一段代码吧.
    public Form1()
            {
                InitializeComponent();
                TextBox.CheckForIllegalCrossThreadCalls = false;//关闭跨线程修改控件检查
            }
            Socket sokWatch = null;//负责监听 客户端段 连接请求的  套接字(女生宿舍的大妈)
            Thread threadWatch = null;//负责 调用套接字, 执行 监听请求的线程        //开启监听 按钮
            private void btnStartListen_Click(object sender, EventArgs e)
            {
                //实例化 套接字 (ip4寻址协议,流式传输,TCP协议)
                sokWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //创建 ip对象
                IPAddress address = IPAddress.Parse(txtIP.Text.Trim());
                //创建网络节点对象 包含 ip和port
                IPEndPoint endpoint = new IPEndPoint(address, int.Parse(txtPort.Text.Trim()));
                //将 监听套接字  绑定到 对应的IP和端口
                sokWatch.Bind(endpoint);
                //设置 监听队列 长度为10(同时能够处理 10个连接请求)
                sokWatch.Listen(10);
                threadWatch = new Thread(StartWatch);
                threadWatch.IsBackground = true;
                threadWatch.Start();
                txtShow.AppendText("启动服务器成功......\r\n");
            }        //Dictionary<string, Socket> dictSocket = new Dictionary<string, Socket>();
            Dictionary<string, ConnectionClient> dictConn = new Dictionary<string, ConnectionClient>();
            
            bool isWatch = true;        #region 1.被线程调用 监听连接端口
            /// <summary>
            /// 被线程调用 监听连接端口
            /// </summary>
            void StartWatch()
            {
                while (isWatch)
                {
                    //threadWatch.SetApartmentState(ApartmentState.STA);
                    //监听 客户端 连接请求,但是,Accept会阻断当前线程
                    Socket sokMsg = sokWatch.Accept();//监听到请求,立即创建负责与该客户端套接字通信的套接字
                    ConnectionClient connection = new ConnectionClient(sokMsg, ShowMsg, RemoveClientConnection);
                    //将负责与当前连接请求客户端 通信的套接字所在的连接通信类 对象 装入集合
                    dictConn.Add(sokMsg.RemoteEndPoint.ToString(), connection);
                    //将 通信套接字 加入 集合,并以通信套接字的远程IpPort作为键
                    //dictSocket.Add(sokMsg.RemoteEndPoint.ToString(), sokMsg);
                    //将 通信套接字的 客户端IP端口保存在下拉框里
                    cboClient.Items.Add(sokMsg.RemoteEndPoint.ToString());
                    ShowMsg("接收连接成功......");
                    //启动一个新线程,负责监听该客户端发来的数据
                    //Thread threadConnection = new Thread(ReciveMsg);
                    //threadConnection.IsBackground = true;
                    //threadConnection.Start(sokMsg);
                }
            } 
            #endregion        bool isRec = true;//与客户端通信的套接字 是否 监听消息        #region 发送消息 到指定的客户端 -btnSend_Click
            //发送消息 到指定的客户端
            private void btnSend_Click(object sender, EventArgs e)
            {
                //byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(txtInput.Text.Trim());
                //从下拉框中 获得 要哪个客户端发送数据
                string connectionSokKey = cboClient.Text;
                if (!string.IsNullOrEmpty(connectionSokKey))
                {
                    //从字典集合中根据键获得 负责与该客户端通信的套接字,并调用send方法发送数据过去
                    dictConn[connectionSokKey].Send(txtInput.Text.Trim());
                    //sokMsg.Send(arrMsg);
                }
                else
                {
                    MessageBox.Show("请选择要发送的客户端~~");
                }
            } 
            #endregion
    当然那个选择下拉框,你可以换成listBox 选择 !LZ 你看看吧,希望能帮到你 !下面是客户端.
     public Form1()
            {
                InitializeComponent();
                TextBox.CheckForIllegalCrossThreadCalls = false;
            }        Socket sokClient = null;//负责与服务端通信的套接字
            Thread threadClient = null;//负责 监听 服务端发送来的消息的线程
            bool isRec = true;//是否循环接收服务端数据        private void btnConnect_Click(object sender, EventArgs e)
            {
                //实例化 套接字
                sokClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //创建 ip对象
                IPAddress address = IPAddress.Parse(txtIP.Text.Trim());
                //创建网络节点对象 包含 ip和port
                IPEndPoint endpoint = new IPEndPoint(address, int.Parse(txtPort.Text.Trim()));
                //连接 服务端监听套接字
                sokClient.Connect(endpoint);
                
                //创建负责接收 服务端发送来数据的 线程
                threadClient = new Thread(ReceiveMsg);
                threadClient.IsBackground = true;
                //如果在win7下要通过 某个线程 来调用 文件选择框的代码,就需要设置如下
                threadClient.SetApartmentState(ApartmentState.STA);
                threadClient.Start();
            }        /// <summary>
            /// 接收服务端发送来的消息数据
            /// </summary>
            void ReceiveMsg()
            {
                while (isRec)
                {
                    byte[] msgArr = new byte[1024 * 1024 * 1];//接收到的消息的缓冲区
                    int length=0;
                    //接收服务端发送来的消息数据
                    length =sokClient.Receive(msgArr);//Receive会阻断线程
                    if (msgArr[0] == 0)//发送来的是文字
                    {
                        string strMsg = System.Text.Encoding.UTF8.GetString(msgArr, 1, length - 1);
                        txtShow.AppendText(strMsg + "\r\n");
                    }
                    else if (msgArr[0] == 1) { //发送来的是文件
                        SaveFileDialog sfd = new SaveFileDialog();
                        //弹出文件保存选择框
                        if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                        {
                            //创建文件流
                            using (FileStream fs = new FileStream(sfd.FileName, FileMode.OpenOrCreate))
                            {
                                fs.Write(msgArr, 1, length - 1);
                                MessageBox.Show("文件保存成功!");
                            }
                        }
                    }
                    else if (msgArr[0] == 2) {
                        ShakeWindow();
                    }
                }
            }
    现在客户端和服务器就能进行通信了,至于界面神马的.你可以自己发挥了,其他的功能大同小异 ! 
      

  4.   


    方案1、只有客户端不要服端,就是P2P的聊程序,A客户端上线广播上线通知,在线客户端更新在线列表,并回应自己在线。 A收到各在线客户端生成在线列表。可就以选择与在线客户端聊天了。下线时广播下线通知,各在线客户端移除在线列表对应的用户。方案2、有服务端,登录注册到服务端,从服务端获取在线列表,选择选择列表用户就可以聊天了。更复杂的话,就得自己定义一套协议进行通信了。C#中 socket、TCP、UDP都可以。
      

  5.   

    以前做过一个 是用udp啊。虽然可能会丢包(一般不会),但速度才是关键呀。
      

  6.   

    额 LZ  QQ还是挺强大的
    模仿的话不好来
    如果LZ是在一个公司中使用那就好办了
    直接设置固定IP访问就可以了