我现在写一个有关于Socket的程序,我已写出来了,可是Server端只能接受一个Client端并且有好几个功能都没有实现,请各位高帮帮忙。怎样才能可以接受多台客户端呢?还有怎么才能实现:每个客户端刚请求连接服务端时都用服务器的Port号(固定Port号),可连接上去时服务端下一个自定的Port号(Port+序号)(序号是自动增长的)给该客户端,这个客户程序收到服务器端发来的Port号时,再次用收到的Port号(Port+序号)重新和服务端程序进行再次连接。下一台客户机连接时也是如此。并且时时获取各台客户端程序的行为并以各台客户的Port号列出来显示在服务器端的ListBox控件里。

解决方案 »

  1.   

    下面是我写的服务器端的程序,各位帮我看看:#region 监听 //开始监听
    private void btnListen_Click(object sender, System.EventArgs e)
    {
    try
    {
    IPHostEntry myHost = new IPHostEntry();
    myHost = Dns.GetHostByName(txtServer.Text);
    string IPstring = myHost.AddressList[0].ToString();
    myIP = IPAddress.Parse(IPstring);
    }
    catch
    {
    MessageBox.Show("您输入的IP地址格式不正确,请重新输入!");
    } try
    {
    myServer = new IPEndPoint(myIP,Int32.Parse(txtPort.Text.Trim()));
    mySocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
    mySocket.Bind(myServer);
    mySocket.Listen(50); txtState.AppendText("主机"+txtServer.Text+"端口"+txtPort.Text+"开始监听.....\r\n"); //线程
    Thread thread = new Thread(new ThreadStart(target));
    thread.Start();
    }
    catch(Exception ee)
    {
    txtState.AppendText(ee.Message+"\r\n");
    }
    } //线程同步方法target
    private void target()
    {
    while(true)
    {
    //设为非终止
    myReset.Reset(); mySocket.BeginAccept(new AsyncCallback(AcceptCallback),mySocket); //阻塞当前线程,直到收到请求信号
    myReset.WaitOne();
    }
    } //异步回调方法AcceptCallback
    private void AcceptCallback(IAsyncResult ar)
    {
    //将事件设为终止
    myReset.Set(); Socket listener = (Socket)ar.AsyncState;
    handler = listener.EndAccept(ar); //获取状态
    StateObject state = new StateObject();
    state.workSocket = handler; txtState.AppendText("与客户建立连接。\r\n"); try
    {
    byte[] byteData = System.Text.Encoding.BigEndianUnicode.GetBytes("已经准备好,请通话!"+"\r\n");
    //开始发送
    handler.BeginSend(byteData,0,byteData.Length,0,new AsyncCallback(SendCallback),handler);
    }
    catch(Exception ee)
    {
    MessageBox.Show(ee.Message);
    } //线程
    Thread thread = new Thread(new ThreadStart(begReceive));
    thread.Start();
    } //异步回调方法 SendCallback
    private void SendCallback(IAsyncResult ar)
    {
    try
    {
    handler = (Socket)ar.AsyncState;
    int bytesSent = handler.EndSend(ar);
    }
    catch(Exception ee)
    {
    MessageBox.Show(ee.Message);
    }
    } //线程同步方法begReceive
    private void begReceive()
    {
    StateObject state = new StateObject();
    state.workSocket = handler;
    handler.BeginReceive(state.buffer,0,StateObject.BufferSize,0,new AsyncCallback(ReadCallback),state);
    } //异步回调方法ReadCallback
    private void ReadCallback(IAsyncResult ar)
    {
    StateObject state = (StateObject) ar.AsyncState;
    Socket tt = state.workSocket; //结束读取并获取读取字节数
    int bytesRead = handler.EndReceive(ar);
    state.sb.Append(System.Text.Encoding.BigEndianUnicode.GetString(state.buffer,0,bytesRead));
    string content = state.sb.ToString();
    state.sb.Remove(0,content.Length);
    rtbIncept.AppendText(content+"\r\n"); //重新开始读取数据
    tt.BeginReceive(state.buffer,0,StateObject.BufferSize,0,new AsyncCallback(ReadCallback),state);
    }#endregion 监听
      

  2.   

    //发送信息
    private void btnSend_Click(object sender, System.EventArgs e)
    {
                try
    {
    byte[] byteData = System.Text.Encoding.BigEndianUnicode.GetBytes(rtbSend.Text+"\r\n"); //开始发送数据
    handler.BeginSend(byteData,0,byteData.Length,0,new AsyncCallback(SendCallback),handler);
    }
    catch(Exception ee)
    {
    MessageBox.Show(ee.Message);
    }
    }
      

  3.   

    //停止监听
    private void btnStop_Click(object sender, System.EventArgs e)
    {
    try
    {
    mySocket.Close();
    txtState.AppendText("主机"+txtServer.Text+"端口"+txtPort.Text+"停止监听"+"\r\n");
    }
    catch
    {
    MessageBox.Show("监听尚未开始,关闭无效!");
    }
    }
      

  4.   

    用UdpClient可以使多台客户机连接:UdpClient udpClient = new UdpClient();
    // Creates an IPAddress to use to join and drop the multicast group.
    IPAddress multicastIpAddress = IPAddress.Parse("239.255.255.255");try{
         // The packet dies after 50 router hops.
         udpClient.JoinMulticastGroup(multicastIpAddress, 50);
    }
    catch ( Exception e ){
        Console.WriteLine( e.ToString());
    }
      

  5.   

    TO: zjroland(孤独侠客)
     您说具体一些好吗?
     请各位帮帮忙呀!
      

  6.   

    好像你接收到一个连接到就没有继续执行侦听了
    应该像接收和发送一样,执行异步侦听才对进行回调
    再加一方法吧
    这是我写的,是做成服务的
    this.skWap.Listen(100)
    this.skWap.BeginAccept (new AsyncCallback (Wap_Accept_Callback),this.skWap );
    /// <summary>
    /// 异步监听回调(wap)
    /// </summary>
    /// <param name="r"></param>
    private void Wap_Accept_Callback(System.IAsyncResult r)
    {
    Socket s=this.skWap.EndAccept (r);
    string strIP=this.SocketIP (s);
    StateObject st=new StateObject(s);
    try
    {
    s.BeginReceive(st.Buffer,0,st.Buffer.Length,SocketFlags.None,
    new AsyncCallback(Wap_Receive_Callback),st);
    // object o=(object)s;
    // WapCollect.Add (o,strIP);
    //写日志
    iCount++;
    this.WapCount("收到来自" + strIP +"的第"+ iCount +"个连接"); }
    catch(System.Net.Sockets.SocketException se)
    {
    this.Error (se.NativeErrorCode ,se.Message );
    }
    catch(System.Exception ex)
    {
    this.Error(1,ex.Message);
    }

    this.skWap.BeginAccept (new AsyncCallback (Wap_Accept_Callback),this.skWap );
    }
      

  7.   

    服务器的Socket要写侦听端口的数目。不然只侦听一个就关闭。
      

  8.   

    我也是用异步侦听的呀,我加了也不行。
    帮帮我呀!!!!!!!!!!!
    还有一个问题:怎么才能动态建立Socket对象。我想给每个连接的客户端都建立一个Socket对象,怎么实现?比如:当某个客户端连接时(用固定的端口号如100)连接成功后发送一个"Start"信号给服务端,服务端接收到"Start"信号后把实际端口号(100+i)(i是一个自动增长的变量)发送给这个客户端,在发送的同时服务器端自动建立一个Socket+"100+i"的Socket对象进行对端口100+i进行监听,客户端收到端口号100+i后断开原来的连接重新以100+i进行连接。请问怎么才能实现动态新建这个Socket对象?
      

  9.   

    我觉得这样做比较好:
    服务器有一个服务,专门用来给客户机发送动态生成的端口号,
    客户机发送端口请求信息,服务器相应,发送端口号,这一系列动作用UDP来实现,而不是TCP;服务器监视个客户机的即时行为用TCP来做。
      

  10.   

    TO: storm97(风暴不再)
      你能帮我说清楚一些,好吗?
    你有这方面的例子不,给我一个好不好?
    谢谢你!!!!!!!!!!!!
      

  11.   

    StateObject state = (StateObject) ar.AsyncState;
    Socket tt = state.workSocket; //结束读取并获取读取字节数
    int bytesRead = handler.EndReceive(ar);
    state.sb.Append(System.Text.Encoding.BigEndianUnicode.GetString(state.buffer,0,bytesRead));
    string content = state.sb.ToString();
    state.sb.Remove(0,content.Length);
    rtbIncept.AppendText(content+"\r\n"); //重新开始读取数据
    tt.BeginReceive(state.buffer,0,StateObject.BufferSize,0,new AsyncCallback(ReadCallback),state);这句话有严重的问题。应改成
    try
    {
    client.endConnect(iar);
    client.BeginReceive(data,0,size,Socket.None,new AstncCallBack(ReceiveData),client);
    } catch(SocketException)
    {
      MessageBox.show(''error');
    }
    等等的这种模式。。
    你先改改,有什么不懂得再问
    另一个是,不仅要在连接用异步,在发送数据,接收数据,都得用异步,这样才叫真正的异步传输。
      

  12.   

    TO:weiKun_(Virus)
    我改过来还是这样,不能连接多个客户端。我的需求是这样:要求每个客户端连接上来时都有一个自己的端口号(Port)和Socket对象,这样就服务器就容易对各个客户端进行管理。可是每个客户刚要和服务端连接时都用固定的端号(Port)和服务器名进行连接。你帮我写好不好?我现在好乱。求求你了。
      

  13.   

    TO:_weiKun_(Virus):
      你好!我已我把程序发到你邮箱了,你帮我看一下,帮我完成这个任务。谢谢您!!!!
      

  14.   

    TO:_weiKun_(Virus)
    你发给我的文件打不开,你在我发给你的那个工程文件的基础上写,好吗?我等你的好消息!!!非常感谢您!!!!我会给多分给你的。再次谢谢
      

  15.   

    我是用。net 2003写的,我在哈尔滨
      

  16.   

    那怎么办呀!你帮帮我好不好!要不我完蛋了。你帮我用Visual C#来在我发给你的工程文件的基础上写好吗?求你了.......
      

  17.   

    你把我的文件不用.NET打开,用ULTRAEDIT 打开它得CS文件,即可呀,我是另外写得工程,没有用你的工程,你用我的连接,和发送,接受得函数即可。我就不给你写了,我在给你发一份。
      

  18.   

    TO:_weiKun_(Virus)
    那我怎么获取各个连接的客户端的IP地址和机器名呢?怎么断开指定的客户端呢?怎么给指定的客户端发信息呢?
      

  19.   

    tcp只能和一个客户进行连接,用UDP吧
      

  20.   

    private void btnStart_Click(object sender, System.EventArgs e)
    {
    try
    {
    IPHostEntry myHost = new IPHostEntry();
    myHost = Dns.GetHostByName(txtServer.Text);
    string IPstring = myHost.AddressList[0].ToString();
    myIP = IPAddress.Parse(IPstring);
    }
    catch
    {
    MessageBox.Show("您输入的IP地址格式不正确,请重新输入!");
    } try
    {
    myServer = new IPEndPoint(myIP,Int32.Parse(txtPort.Text.Trim()));
    mySocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
    mySocket.Bind(myServer);
    mySocket.Listen(50); txtState.Text = "主机"+txtServer.Text+"端口"+txtPort.Text+"开始监听....."; //线程
    Thread thread = new Thread(new ThreadStart(target));
    thread.Start();
    }
    catch(Exception ee)
    {
    txtState.Text = ee.Message;
    } }//end btnStart_Click //线程同步方法target
    private void target()
    {
    while(true)
    {
    //设为非终止
    myReset.Reset(); mySocket.BeginAccept(new AsyncCallback(AcceptCallback),mySocket); //阻塞当前线程,直到收到请求信号
    myReset.WaitOne();
    }
    }//end target //异步回调方法AcceptCallback
    private void AcceptCallback(IAsyncResult ar)
    {
    //将事件设为终止
    myReset.Set(); Socket listener = (Socket)ar.AsyncState;
    handler = listener.EndAccept(ar); //获取状态
    StateObject state = new StateObject();
    state.workSocket = handler; txtState.Text = "与客户建立连接。\r\n"; ListViewItem item ;
    //向lvIncept控件写入一条新进入的客户信息
    string[] itemName = new string[3];
    itemName[0] = handler.RemoteEndPoint.ToString(); 
    itemName[1] = DateTime.Now.ToString(); 
    itemName[2] = "正在连通状态.................................................";
    item = new ListViewItem(itemName,0);
    item.Checked=false; //统计连接客户端数
    intClient++;
    txtCount.Text = intClient.ToString(); lvIncept.Items.Add(item); try
    {
    byte[] byteData = System.Text.Encoding.UTF8.GetBytes("已经准备好,请通话!"+"\r\n");
    //开始发送
    handler.BeginSend(byteData,0,byteData.Length,0,new AsyncCallback(SendCallback),handler);
    }
    catch(Exception ee)
    {
    MessageBox.Show(ee.Message);
    } //线程
    Thread thread = new Thread(new ThreadStart(begReceive));
    thread.Start(); }//end AcceptCallback //异步回调方法 SendCallback
    private void SendCallback(IAsyncResult ar)
    {
    try
    {
    handler = (Socket)ar.AsyncState;
    int bytesSent = handler.EndSend(ar);
    }
    catch(Exception ee)
    {
    MessageBox.Show(ee.Message);
    } }//end SendCallback //线程同步方法begReceive
    private void begReceive()
    {
    StateObject state = new StateObject();
    state.workSocket = handler;
    handler.BeginReceive(state.buffer,0,StateObject.BufferSize,0,new AsyncCallback(ReadCallback),state); //中断指定的客户端
    if(ClickBreak)
    {
    BreakClient(ref handler);
    } string strAccept = "";
    strAccept = state.sb.Append(System.Text.Encoding.UTF8.GetString(state.buffer,0,24)).ToString();
    //sw.Write(handler.RemoteEndPoint.ToString()+":");
    sw.WriteLine(strAccept);
    //MessageBox.Show(strAccept);
    txtSend.Text = strAccept;
    sw.Flush();

    }//end begReceive //异步回调方法ReadCallback
    private void ReadCallback(IAsyncResult ar)
    {
    StateObject state = (StateObject) ar.AsyncState;
    Socket tt = state.workSocket; //重新开始读取数据
    try
    {
    //结束读取并获取读取字节数
    //int bytesRead = handler.EndReceive(ar);
    int bytesRead = tt.EndReceive(ar);
    state.sb.Append(System.Text.Encoding.UTF8.GetString(state.buffer,0,bytesRead));
    string content = state.sb.ToString();
    state.sb.Remove(0,content.Length); //txtSend.Text = content;
    textBox1.AppendText(tt.RemoteEndPoint.ToString()+": "+content+"\r\n"); tt.BeginReceive(state.buffer,0,StateObject.BufferSize,0,new AsyncCallback(ReadCallback),state);
    }
    catch
    {
    //从lvIncept控件删除相应的信息
    if(ClickBreak == false)
    {
    for(int i=0;i<lvIncept.Items.Count;i++)
    {
    if(lvIncept.Items[i].SubItems[0].Text == tt.RemoteEndPoint.ToString())
    {
    lvIncept.Items[i].Remove();
    }
    }
    } intClient--;
    txtCount.Text = intClient.ToString();
    }

    //控制颜色
    CortrolColor(ref lvIncept); }//end ReadCallback //发送信息
    private void SendMessage(string strSend)
    {
    try
    {
    byte[] byteData = System.Text.Encoding.UTF8.GetBytes(strSend); /*
    for(int i = 0;i<lvIncept.Items.Count;i++)
    {
    if(lvIncept.Items[i].Checked)
    {
    if(lvIncept.Items[i].SubItems[0].Text == handler.RemoteEndPoint.ToString())
    {
    //开始发送数据
    handler.BeginSend(byteData,0,byteData.Length,0,new AsyncCallback(SendCallback),handler);
    }
    }
    }
    */ //开始发送数据
    handler.BeginSend(byteData,0,byteData.Length,0,new AsyncCallback(SendCallback),handler);
    }
    catch(Exception ee)
    {
    MessageBox.Show(ee.Message);
    } }//end SendMessage