为何我的Socket客户端只能发送服务端一次,第二次窗体就动不了了。先看客户端,为一个Console项目        static void Main(string[] args)
        {
            //用于表示客户端发送的信息长度
            int recv;
            //用于缓存客户端所发送的信息,通过socket传递的信息必须为字节数组
            byte[] data = new byte[1024];            //本机预使用的IP和端口
            IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9050);
            Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            newsock.Bind(ipep);//绑定
            newsock.Listen(10);//监听
            Console.WriteLine("waiting for a client");
            //当有可用的客户端连接尝试时执行,并返回一个新的socket,用于与客户端之间的通信
            Socket client = newsock.Accept();
            IPEndPoint clientip = (IPEndPoint)client.RemoteEndPoint;
            Console.WriteLine("connect with client:" + clientip.Address + " at port:" + clientip.Port);
            string welcome = "welcome here!";
            data = Encoding.ASCII.GetBytes(welcome);
            // 当Client连接上Server后,发送给Client信息"welcome here!"
            client.Send(data, data.Length, SocketFlags.None);
            // 用死循环来不断的从客户端获取信息
            while (true)
            {
                
                data = new byte[1024];
                recv = client.Receive(data);
                Console.WriteLine("Client传来数据长度 = " + recv);
                if (recv == 0)//当信息长度为0,说明客户端连接断开
                    break;
                
                // 打印Client传来的信息
                Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));                // 回传Client传来的信息
                client.Send(data, recv, SocketFlags.None);
            }            Console.WriteLine("Disconnected from" + clientip.Address);
            client.Close();
            newsock.Close();
        }   客户端是一个窗体应用,用户填写服务端IP和Port,然后填入字符串,点击“发送”,想服务端发送。
然后显示从服务端返回的字符串。遇到的问题是,第一次可以发送,并返回。第二次,窗体就不动了。        private void btnSend_Click(object sender, EventArgs e)
        {
            Socket newclient = null;                      if (this.txtServerIP.Text != string.Empty && this.txtServerPort.Text != string.Empty)
            {                // 设置好
                newclient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                string ipadd = this.txtServerIP.Text.Trim();
                int port = Convert.ToInt32(this.txtServerPort.Text.Trim());
                IPEndPoint ie = new IPEndPoint(IPAddress.Parse(ipadd), port);//服务器的IP和端口
                // 连接
                try
                {
                    //因为客户端只是用来向特定的服务器发送信息,所以不需要绑定本机的IP和端口。不需要监听。
                    newclient.Connect(ie);
                }
                catch (Exception)
                {
                    MessageBox.Show("连接服务器出错");
                    newclient.Close();
                    return;
                }
                // 发送
                string SC = this.txtSC.Text.Trim();
                newclient.Send(Encoding.ASCII.GetBytes(SC));
                // 接收
                byte[] data = new byte[8096];
                int recv = newclient.Receive(data);
                string stringdata = Encoding.ASCII.GetString(data, 0, recv);
                this.txtACS.Text = stringdata;    // 显示从服务端发来的字符串 
            }
            else
            {
                MessageBox.Show("IP与Port请输入完整!");
            }
        }

解决方案 »

  1.   

    你可以把Socket newclient = null;等一些定义的套接字的定义成全局变量,只需在发送按钮里面放发送的字符串的关键代码就可以了。不要每次发送都定义一个套接字。有可能是你上次的套接字的端口都没有释放掉,你又在按钮里面去重新定义套接字,就会出现问题。
      

  2.   

    我从来不回答在socket问题中揪扯上winform的问题。原因是,网上有太多的所谓低级的demo是在一个winform界面揪扯socket的,物以类聚,所以不回答。一个专业的程序员的基本素质,就是它学会了根据对象的职责进行封装。你写一个服务、客户组件用于实现c/s通讯,跟谁调用它不用揪扯在一起。
      

  3.   


    这是一个基本知识:并发地new出来1000个socket,它们connet同一个服务器的同一个端口,也是很正常的。同样地,假设有100个客户端,每一个客户端有100个并发连接连到同一个服务器的同一个端口上,也是很正常的。这都不行,就别做通讯了。