我是个菜鸟
最近研究Socket网络编程中
正在做一个基于TCP的文字游戏
要求是一服务端
N(N>1)个客户端以前做的练的全都是单对单形式的编程
到了这里完全没了头绪按照我原先的设想服务端一个Listen进入永久循环监听
客户端连接后
服务端创建Socket
处理完数据之后执行Socket.Close()方法关闭套接字
等待新的连接进入
再创建Socket就行了所以在申明部分我加上了-------------------------------01
private Socket Server_Socket;
在永久循环中对其实例化-------------------------------02
Server_Socket = Listen.AcceptSocket();
处理完数据之后---------------------------------------03
Server_Socket.Close();调试时一切顺利
第一个用户连接
数据交互都非常顺利但是第2个用户连接时就会出现
套接字只能用一次(大致是这个意思)的异常
而且第2个用户也无法和服务器之间进行数据交互异常是第2步进行实例化的时引发的
为了解决
我在数据处理完毕后强行 Server_Socket = null;但是异常还是在第2步的时候引发了同时
服务端执行开始服务器
再执行关闭服务器
再执行开始服务器时也会出现这个异常就是Socket只能用一次
我要崩溃了各位达人们帮帮小弟我吧~~
十万分感激

解决方案 »

  1.   

    Socket 类为网络通信提供了一套丰富的方法和属性。Socket 类允许您使用 ProtocolType 枚举中所列出的任何一种协议执行异步和同步数据传输。Socket 类遵循异步方法的 .NET Framework 命名模式;例如,同步 Receive 方法对应于异步 BeginReceive 和 EndReceive 方法。如果应用程序在执行期间只需要一个线程,请使用下面的方法,这些方法适用于同步操作模式。 如果当前使用的是面向连接的协议(如 TCP),则服务器可以使用 Listen 方法侦听连接。Accept 方法处理任何传入的连接请求,并返回可用于与远程主机进行数据通信的 Socket。可以使用此返回的 Socket 来调用 Send 或 Receive 方法。如果要指定本地 IP 地址和端口号,请在调用 Listen 方法之前先调用 Bind 方法。如果不调用 Bind,基础服务提供程序将为您分配这些值。此后,可以使用 LocalEndPoint 属性来标识分配给 Socket 的 IP 地址和端口号。如果想连接到侦听主机,请调用 Connect 方法。若要进行数据通信,请调用 Send 或 Receive 方法。 
    如果当前使用的是无连接协议(如 UDP),则根本不需要侦听连接。调用 ReceiveFrom 方法可接受任何传入的数据报。使用 SendTo 方法可将数据报发送到远程主机。 
    若要在执行过程中使用单独的线程处理通信,请使用下面的方法,这些方法适用于异步操作模式。 如果当前使用的是面向连接的协议(如 TCP),则可使用 Socket、BeginConnect 和 EndConnect 方法来连接侦听主机。通过使用 BeginSend 和 EndSend 方法,或者使用 BeginReceive 和 EndReceive 方法,可以进行异步数据通信。可以使用 BeginAccept 和 EndAccept 处理传入的连接请求。 
    如果当前使用的是无连接协议(如 UDP),则可以使用 BeginSendTo 和 EndSendTo 来发送数据报,而使用 BeginReceiveFrom 和 EndReceiveFrom 来接收数据报。 
    当数据发送和数据接收完成之后,可使用 Shutdown 方法来禁用 Socket。在调用 Shutdown 之后,可调用 Close 方法来释放与 Socket 关联的所有资源。Socket 类允许使用 SetSocketOption 方法来配置 Socket。可使用 GetSocketOption 方法来检索这些设置。注意   如果编写较简单的应用程序,而且只需同步数据传输,则可以考虑使用 TcpClient、TcpListener 和 UdpClient。这些类为 Socket 通信提供了更简单、对用户更友好的接口。
    示例
    下面的示例显示如何使用 Socket 类向 HTTP 服务器发送数据和接收响应。
      

  2.   

    using System;
    using System.Text;
    using System.IO;
    using System.Net;
    using System.Net.Sockets;public class mySocket
    {
       private static Socket connectSocket(string server, int port)
       {
          Socket s = null;
          IPHostEntry iphe = null;
        
        
        try
          {
            // Get host related information.
          iphe = Dns.Resolve(server);
        
        
          // Loop through the AddressList to obtain the supported AddressFamily. This is to avoid
          // an exception to be thrown if the host IP Address is not compatible with the address family
          // (typical in the IPv6 case).
            foreach(IPAddress ipad in iphe.AddressList)
            {
                IPEndPoint ipe = new IPEndPoint(ipad, port);            Socket tmpS = 
                  new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);          tmpS.Connect(ipe);        if(tmpS.Connected)
                {
                  s = tmpS;
                  break;
                }
                else
                  continue;
            }
          }
        
          catch(SocketException e) 
          {
              Console.WriteLine("SocketException caught!!!");
              Console.WriteLine("Source : " + e.Source);
              Console.WriteLine("Message : " + e.Message);
          }
          catch(Exception e)
          {
              Console.WriteLine("Exception caught!!!");
              Console.WriteLine("Source : " + e.Source);
              Console.WriteLine("Message : " + e.Message);
          }
          return s;    }
      // This method requests the home page content for the passed server.
      // It displays the number of bytes received and the page content.
      private static string socketSendReceive(string server, int port) 
        {
          //Set up variables and String to write to the server.
          Encoding ASCII = Encoding.ASCII;
          string Get = "GET / HTTP/1.1\r\nHost: " + server + 
                     "\r\nConnection: Close\r\n\r\n";
          Byte[] ByteGet = ASCII.GetBytes(Get);
          Byte[] RecvBytes = new Byte[256];
          String strRetPage = null;      // Create a socket connection with the specified server and port.
          Socket s = connectSocket(server, port);      if (s == null)
            return ("Connection failed");
          
          // Send request to the server.
          s.Send(ByteGet, ByteGet.Length, 0);  
            
        
          // Receive the server  home page content.
          Int32 bytes = s.Receive(RecvBytes, RecvBytes.Length, 0);    
       
          // Read the first 256 bytes.
          strRetPage = "Default HTML page on " + server + ":\r\n";
          strRetPage = strRetPage + ASCII.GetString(RecvBytes, 0, bytes);    
          while (bytes > 0)
          {
            bytes = s.Receive(RecvBytes, RecvBytes.Length, 0);
            strRetPage = strRetPage + ASCII.GetString(RecvBytes, 0, bytes);
          }
               
          return strRetPage;
        }
        
        public static void Main(string[] args) 
        {
          string host;
          int port = 80;      if (args.Length == 0)
              // If no server name is passed as argument to this program, use the current 
              // host name as default.
              host = Dns.GetHostName();
          else
              host = args[0];
          string result = socketSendReceive(host, port); 
           
          Console.WriteLine(result);
       }
      
    }
      

  3.   

    楼上这个代码是你自己写的还是网上找的?
    客户端发送的我已经完成了
    现在主要问题集中在服务端
    之前用的是TcpListener加Socket加一个线程 侦听处理服务端传入的连接
    但是无法为新的连接创建Socket实例楼上写的意思是服务端用Socket侦听并异步接收吗?
    我还没试过
    对于多人通信可行吗?拜托在看看我的问题好吗另外谁有多点通信的例子能发我一份吗谢谢
    [email protected]不要单对单的
      

  4.   

    但是第2个用户连接时就会出现
    套接字只能用一次(大致是这个意思)的异常是因为你服务器端的接收,肯定每次都是用Server_Socket接的,而且没用用一个局部的socket来得获得,每一次是没关系的,当第二次是,第二个连接就取代了第一个连接。。
    我开始做这个东东时,也出现同样的错误。。~~。。
      

  5.   

    dazhu2说得没错啊。gotohide你所说的问题是因为没有生成一个新的连接。