#窗体中Socket异步编程,一个服务器能同时和多个客户端互发送数据,但是我这个有错误,不能同时和多个客户端通讯socket

解决方案 »

  1.   

    服务端
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Net.Sockets;
    using System.Threading;
    using System.Net;
    using System.IO;namespace Socket套接字
    {
        public partial class Form1 : Form
        {
             //server-用于处理客户端连接请求的socket
                Socket clientSocket = null;
               public delegate void dgs(string msg);
            public Form1()
            {
                InitializeComponent();
            }            //server-侦听方法
                private void listen()
                {
                    //获取服务器IP
                    string hostName = Dns.GetHostName();
                    IPAddress[] ip = Dns.GetHostAddresses(hostName);
                    IPAddress HostIp = ip[1];                //创建一个网络端点
                    IPEndPoint iep = new IPEndPoint(HostIp,8882);                //创建服务端服务端套接字
                    Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);                //将套接字与网络端点绑定
                    serverSocket.Bind(iep);                //将套接字置为侦听状态,并设置最大队列数为100
                    serverSocket.Listen(100);
                   // serverSocket.BeginAccept(new AsyncCallback(Accept), serverSocket);
                   
                    //以同步方式从侦听套接字的连接请求队列中提取第一个挂起的连接请求,然后创建并返回新的 Socket
                    //新的套接字:包含对方计算机的IP和端口号,可使用这个套接字与本机进行通信   
                  serverSocket.Accept();
                    //if (clientSocket != null)
                    //{
                    //    MessageBox.Show("连接成功!");
                    //}            }            //void Accept(IAsyncResult iar)
                //{
                //    //还原传入的原始套接字
                //    Socket MyServer = (Socket)iar.AsyncState;
                //    //在原始套接字上调用EndAccept方法,返回新的套接字
                //    Socket service = MyServer.EndAccept(iar);
                //}            private  void send_Click(object sender, EventArgs e)
                {
                    timer1.Start();
                    if (this.textBox1.Text != "")//不能发送空消息
                    {
                        try
                        {
                            //发送数据
                            string message = textBox1.Text;
                            byte[] sendbytes = System.Text.Encoding.UTF8.GetBytes(message);
                            int successSendBtyes = clientSocket.Send(sendbytes, sendbytes.Length, SocketFlags.None);
                        }
                        catch (Exception exp)
                        {
                            MessageBox.Show(exp.Message);
                        }
                        //将发送的数据显示到对话窗口并使对话窗口的滚动条一直停留在最下方
                        this.textBox2.Text += "服务器:" + "\r\n" + textBox1.Text + "\r\n";//发完一条消息就换行显示
                        this.textBox2.SelectionStart = this.textBox2.Text.Length;
                        this.textBox2.ScrollToCaret();
                        this.textBox1.Text = "";//将发送窗口清空                }
                    else
                    {
                        MessageBox.Show("发送内容不能为空");
                    }            }            private void Form1_Load(object sender, EventArgs e)
                {
                    
                    //server-创建并运行侦听线程
                    Thread threadListen = new Thread(new ThreadStart(listen));
                    threadListen.Start();
                }            private void timer1_Tick(object sender, EventArgs e)
                {
                   
                    byte[] receiveBytes = new byte[1024];
                    //如果侦听后取得客户端连接,并且客户端的缓冲区中有内容可读,开始接收数据
                    if (clientSocket != null)
                    {                    if (clientSocket.Poll(100, SelectMode.SelectRead))
                        {
                            int successReceiveBytes = clientSocket.Receive(receiveBytes);
                            this.textBox2.Text += "客户端:" + "(" + clientSocket.RemoteEndPoint.ToString() + ")" + "\r\n" +
                                 System.Text.Encoding.UTF8.GetString(receiveBytes, 0, successReceiveBytes) + "\r\n";
                            this.textBox2.SelectionStart = this.textBox2.Text.Length;//使对话窗口的滚动条一直停留在最下方
                            this.textBox2.ScrollToCaret();
                        }                }
                }    }
    }
      

  2.   

    客户端
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Net;
    using System.Net.Sockets;namespace Cilent客户端
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
            Socket clientSocket = null;//客户端套接字
            private void Form1_Load(object sender, EventArgs e)
            {
                timer1.Start();
                try
                {
                    //建立与服务器连接的套接字
                    IPAddress ip = IPAddress.Parse("127.0.0.1");
                    IPEndPoint iep = new IPEndPoint(ip,8882);
                    clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    clientSocket.BeginConnect(iep, new AsyncCallback(Connect), clientSocket);
                    textBox2.Text = "连接成功" + "\r\n";            }
                catch (Exception exp)
                {
                    MessageBox.Show(exp.Message);
                }
            }
            void Connect(IAsyncResult iar)
            {
                Socket client = (Socket)iar.AsyncState;
                try
                {
                    client.EndConnect(iar);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.ToString());
                }
                finally
                {            }
            }
            private void timer1_Tick(object sender, EventArgs e)
            {
                byte[] receiveBytes = new byte[1024];
                if (clientSocket.Poll(100, SelectMode.SelectRead))
                {
                   int successReceiveBytes = clientSocket.Receive(receiveBytes);
                    this.textBox2.Text += "服务器:" + "\r\n" +
                                System.Text.Encoding.UTF8.GetString(receiveBytes, 0, successReceiveBytes) + "\r\n";
                    this.textBox2.SelectionStart = this.textBox2.Text.Length;//使对话窗口的滚动条一直停留在最下方
                    this.textBox2.ScrollToCaret();
                }      
            }        private void button1_Click(object sender, EventArgs e)
            {
                
                if (this.textBox1.Text != "")
                {
                    try
                    {
                        //发送数据
                        string message = textBox1.Text;
                        byte[] sendbytes = System.Text.Encoding.UTF8.GetBytes(message);
                        int successSendBtyes = clientSocket.Send(sendbytes, sendbytes.Length, SocketFlags.None);
                    }
                    catch (Exception exp)
                    {
                        MessageBox.Show(exp.Message);
                    }
                    //将发送的数据显示到对话窗口并使对话窗口的滚动条一直停留在最下方
                    this.textBox2.Text += "我自己:" + "\r\n" + this.textBox1.Text + "\r\n";//发完一条消自己息就换行显示
                    this.textBox2.SelectionStart = this.textBox2.Text.Length;
                    this.textBox2.ScrollToCaret();
                    this.textBox1.Text = "";//将发送窗口清空
                }
                else
                {
                    MessageBox.Show("发送内容不能为空");
                }
            }
        }
    }
      

  3.   

                private void listen()
                 {
                     string hostName = Dns.GetHostName();
                     IPAddress[] ip = Dns.GetHostAddresses(hostName);
                     IPAddress HostIp = ip[1];
                        IPEndPoint iep = new IPEndPoint(HostIp,8882);
                        Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        serverSocket.Bind(iep);
                     serverSocket.Listen(100);
                       serverSocket.Accept();
                 }你这里只有一个 Accept,阻塞一下然后就“完了”,啥有意义的事情都不做,这是为什么?另外,我比较反感那些把代码注释掉的做法。需要把你注释的代码删掉,留下必要的东西,才能开始读代码。你为什么不自己动手吧注释删掉呢?我告诉你一个经验,注释越多,代码越烂。
      

  4.   

    你这里有很很多问题。作为服务器,它应该监听 IPAddress.Any,而不是某一个特定 IP。并且所谓 ip[1] 你怎么就是到每一次都要拿出ip数组中的第二个值,而不是第一个,也不是第三个?当然最关键地是,你应该让代码 serverSocket.BeginAccept 执行,而不是注释掉它。
      

  5.   

    我是初学Socket编程
    至于那个IP[1]是我的本机的IP地址
    如果多个客户端发过来信息
    那么服务器该怎么去识别每个客户端的IP然后回发消息给客户端
    求前辈点拨
      

  6.   

    应该用死循环来接收请求,用list集合把多个客户端装起来,用for循环遍历集合发送消息,不要用forech 
      

  7.   

             //server-侦听方法
                private void listen()
                {
                    //获取服务器IP
                    string hostName = Dns.GetHostName();
                    IPAddress[] ip = Dns.GetHostAddresses(hostName);
                    IPAddress HostIp = ip[1];                //创建一个网络端点
                    IPEndPoint iep = new IPEndPoint(HostIp,8882);                //创建服务端服务端套接字
                    Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);                //将套接字与网络端点绑定
                    serverSocket.Bind(iep);                //将套接字置为侦听状态,并设置最大队列数为100
                    serverSocket.Listen(100);
                   // serverSocket.BeginAccept(new AsyncCallback(Accept), serverSocket);
                   
                    //以同步方式从侦听套接字的连接请求队列中提取第一个挂起的连接请求,然后创建并返回新的 Socket
                    //新的套接字:包含对方计算机的IP和端口号,可使用这个套接字与本机进行通信   
                 while(true){
                serverSocket.BeginAccept(new AsyncCallback(Accept), serverSocket);
               }
      

  8.   

    serverSocket.BeginAccept这个方法是非阻塞的,不需要循环,
    Accept是阻塞的需要循环。
    推荐BeginAccept,http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.beginaccept(v=vs.80).aspx。参考下MSDN吧
      

  9.   

    关于识别Socket的话题。在建立一个Socket的时候就会返回一个Socket对象标示此次连接,它就记录了客户端的一些信息。
      

  10.   

    我改了下代码还有有错误
    求指点
    服务端
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Net.Sockets;
    using System.Threading;
    using System.Net;
    using System.IO;namespace Socket套接字
    {
        public partial class Form1 : Form
        {
             //server-用于处理客户端连接请求的socket
                Socket clientSocket = null;
                Socket service;
            public Form1()
            {
                InitializeComponent();
            }            //server-侦听方法
                private void listen()
                {                IPEndPoint iep = new IPEndPoint(IPAddress.Any,8882); //初始化节点实例
                    //创建服务端服务端套接字
                    Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    try
                    {
                        serverSocket.Bind(iep); //将套接字与网络端点绑定
                        serverSocket.Listen(100); //将套接字置为侦听状态,并设置最大队列数为100
                        //开始接受异步
                        serverSocket.BeginAccept(new AsyncCallback(Accept), serverSocket);
                    }
                    catch (Exception ex)
                    {                    MessageBox.Show(ex.Message);
                    }
                }
                
                void Accept(IAsyncResult iar)//当客户端连接时的处理
                {                
                      Socket MyServer = (Socket)iar.AsyncState; //还原传入的原始套接字
                  
                      service = MyServer.EndAccept(iar);  //在原始套接字上调用EndAccept方法,返回新的套接字
                     //发送数据
                     string message = textBox1.Text;
                     byte[] sendbytes = System.Text.Encoding.UTF8.GetBytes(message);
                     service.Send(sendbytes, sendbytes.Length, 0);//提示消息发送给客户端
                     //等待新的客户的连接
                     MyServer.BeginAccept(new AsyncCallback(Accept), MyServer);
                     while (true)
                     {
                         int recv = service.Receive(sendbytes);
                         string stringdate = Encoding.ASCII.GetString(sendbytes, 0, recv);
                         DateTimeOffset now = DateTimeOffset.Now;
                         //获取客户端的IP
                         string ip = clientSocket.RemoteEndPoint.ToString();
                         //显示客户端发过来的信息
                         this.textBox2.AppendText(ip + " " + now.ToString("G") + " " + stringdate + "\r\n");
           
                     }
                               }            private  void send_Click(object sender, EventArgs e)
                {                this.textBox2.Text = this.textBox1.Text;
                    this.textBox1.Text = "";            }            private void Form1_Load(object sender, EventArgs e)
                {                //server-创建并运行侦听线程                ThreadStart threadListen = new ThreadStart(listen);
                    //实例化新线程
                    Thread th = new Thread(threadListen);
                    th.Start();            }              }
    }
      

  11.   

    客户端
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Net;
    using System.Net.Sockets;
    using System.Threading;namespace Cilent客户端
    {
        public partial class Form1 : Form
        {
            Socket newClient;
            public bool Connected;
            Thread myThread;
            public delegate void MyInvoke(string str);
            public Form1()
            {
                InitializeComponent();
            }        public void Conect()
            { 
                byte[] data = new byte[1024];
                newClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPEndPoint iep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8882);
                try
                {
                    newClient.Connect(iep);
                    Connected = true;
                }
                catch (Exception ex)
                {                MessageBox.Show(ex.Message);
                }
                ThreadStart mythreadStart = new ThreadStart(ReciveMsg);
                myThread = new Thread(mythreadStart);
                myThread.Start();
            }        public void ReciveMsg() 
            {
                while (true)
                {
                    byte[] data = new byte[1024];
                    int revc = newClient.Receive(data);
                    string stringdata = Encoding.UTF8.GetString(data, 0, revc);
                   
                }
            }        private void Form1_Load(object sender, EventArgs e)
            {
                Conect();
            }
            private void button1_Click(object sender, EventArgs e)
            {
             
                if (this.textBox1.Text != "")
                {
                    try
                    {
                        //发送数据
                        int message = textBox1.Text.Length;
                        byte[] sendbytes = new byte[message];
                        sendbytes = Encoding.UTF8.GetBytes(textBox1.Text);
                        int successSendBtyes = newClient.Send(sendbytes);
                    }
                    catch (Exception exp)
                    {
                        MessageBox.Show(exp.Message);
                    }
                    //将发送的数据显示到对话窗口并使对话窗口的滚动条一直停留在最下方
                    this.textBox2.Text += "我自己:" + "\r\n" + this.textBox1.Text + "\r\n";//发完一条消自己息就换行显示
                    this.textBox2.SelectionStart = this.textBox2.Text.Length;
                    this.textBox2.ScrollToCaret();
                    this.textBox1.Text = "";//将发送窗口清空
                }
                else
                {
                    MessageBox.Show("发送内容不能为空");
                }
            }
        }
    }
      

  12.   

     IPEndPoint iep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8882);
    用any看看
      

  13.   

    用ANY的话,联服务器都联不上