【问题标题】:Socket Programming [Socket and Server]Socket编程【Socket与服务器】
【发布时间】:2016-03-29 19:56:17
【问题描述】:

我正在尝试创建消息服务器,但此代码有错误:

报错“每个socket地址只能正常使用一次”

服务器:

class Program
{
    //Server Control
    static bool stop = false;
    static bool pause_listening = false;


    //Server Info
    static int port = 11000;
    static string server_ip = null;

    //User Declaration
   static  List<user> allUsers = new List<user>();
    static int users = 0;

    //IP Address
    static IPAddress ipaddr;
    static IPEndPoint localEP;
    static IPEndPoint userportEP;
    static IPEndPoint temp;
    //Data
    static string data = null;
    static byte[] bytes = new Byte[1024];

    //Threads
    static Thread listener = new Thread(listen);
    static Thread server_control = new Thread(Options);
    static Thread UserPort = new Thread(addUserPort);


    static void Main(string[] args)
    {

        Console.WriteLine("Message Server");
        start();

    }

    static void start()
    {

        server_ip = input("What is your local IPv4 address");
        ipaddr = IPAddress.Parse(server_ip);
        allUsers.Add(new user());

        allUsers[users].name = "Admin";
        allUsers[users].ip = server_ip;
        allUsers[users].desc = "Nimda";
        allUsers[users].id = 0;
        localEP = new IPEndPoint(ipaddr, port);
        userportEP = new IPEndPoint(ipaddr, 1300);

        UserPort.Start();

        listener.Start();
        server_control.Start();
    }
    static void addUserPort()
    {

        Socket listener = new Socket(AddressFamily.InterNetwork,
          SocketType.Stream, ProtocolType.Tcp);

        // Bind the socket to the local endpoint and 
        // listen for incoming connections.
        try
        {
            listener.Bind(userportEP);
            listener.Listen(10);
            Console.WriteLine("User Listener Started");
            // Start listening for connections.
            while (pause_listening || stop != true)
            {

                // Program is suspended while waiting for an incoming connection.
                Socket handler = listener.Accept();
               string value = null;

                // An incoming connection needs to be processed.
                while (true)
                {
                    bytes = new byte[1024];
                    int bytesRec = handler.Receive(bytes);
                    value += Encoding.ASCII.GetString(bytes, 0, bytesRec);

                    if (value.IndexOf("<!EOM>") > -1)
                    {
                        Console.WriteLine("Someone Requested");
                        if(value.IndexOf( "!au") > -1)
                        {
                            String[] rawData = value.Split('|');
                            String[] userData = new String[3];

                           for(int x = 0; x < rawData.Length; x++)
                            {
                                String stringbuff = rawData[x];
                                if(stringbuff.IndexOf("name:") > -1)
                                {
                                    var tempData = stringbuff.Split(':');
                                    userData[x] = tempData[0];
                                }
                               else if (stringbuff.IndexOf("ipaddr:") > -1)
                                {
                                    var tempData = stringbuff.Split(':');
                                    userData[x] = tempData[1];
                                }
                               else if (stringbuff.IndexOf("desc:") > -1)
                                {
                                    var tempData = stringbuff.Split(':');
                                    userData[x] = tempData[2];
                                }
                            }
                            addUser(userData[0], userData[1], userData[2]);
                        }
                        break;
                    }
                }


            }

        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }
    static void listen()
    {

        Socket listener = new Socket(AddressFamily.InterNetwork,
          SocketType.Stream, ProtocolType.Tcp);
        Console.WriteLine("Message Listener Started");
        try
        {
            listener.Bind(localEP);
            listener.Listen(10);

            while (pause_listening || stop != true)
            {

                Socket handler = listener.Accept();
                data = null;

                while (true)
                {
                    bytes = new byte[1024];
                    int bytesRec = handler.Receive(bytes);
                    data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
                    if (data.IndexOf("<!EOM>") > -1 && data.IndexOf("<!META>") > -1)
                    {
                        textSent(data);
                        break;
                    }
                }


            }

        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }


    }
    static void addUser(String name, String ip, String desc) 
    {
        users++;
        allUsers.Add(new user());
        userportEP = new IPEndPoint(IPAddress.Parse(ip), 1300);
        allUsers[users].name = name;
        allUsers[users].ip = ip;
        allUsers[users].desc = desc;
        allUsers[users].id = users;
        byte[] msg = Encoding.ASCII.GetBytes(string.Format("!Join<!PORT>{0}<!PORT><!EOM>", port));
        Socket confirm = new Socket(AddressFamily.InterNetwork,
        SocketType.Stream, ProtocolType.Tcp);
        confirm.Bind(userportEP);
        confirm.Connect(userportEP);
        confirm.Send(msg);
        confirm.Shutdown(SocketShutdown.Both);
        confirm.Close();
    }

    static String input(String inputText)
    {
        Console.WriteLine(inputText);
        return Console.ReadLine();
    }

    static void Options()
    {
        while(stop == false)
        {
            Console.Write("\n Server>>");
           String command = Console.ReadLine();
            switch (command)
            {
                case "stop":
                    stop = true;
                    listener.Abort();
                    UserPort.Abort();
                    StopServer();
                    break;

                default:
                    Console.WriteLine("\t The command \"{0} \" is not valid", command);
                    break;

            }
        }
    }

    static void StopServer()
    {
        Console.WriteLine("Server is stopping");
        Console.Read();
    }

    static void textSent(String text)
    {
    String[] rawText = text.Split(new string[] { "<!META>" }, StringSplitOptions.None) ;
        String message = rawText[0];
        String[] meta = rawText[1].Split(':');
        String package = meta[0] + ": " + message + "<!EOM>";
        SendToAll(package);

    }
    static void SendToAll(String pack)
    {


        byte[] msg = Encoding.ASCII.GetBytes(pack);
        Socket send_socket= new Socket(AddressFamily.InterNetwork,
        SocketType.Stream, ProtocolType.Tcp);
        for (int x = 0; allUsers.Count < x; x++)
        {
            temp = new IPEndPoint(IPAddress.Parse(allUsers[x].ip), port);
            send_socket.Bind(temp);
            send_socket.Connect(temp);
            send_socket.Send(msg);
        }

        send_socket.Shutdown(SocketShutdown.Both);
        send_socket.Close();
    }

}

客户:

class Program
{
    static int port;
    static string server_ip;
    static string ign;
    static string desc;
    static string ip;
    static bool connected = false;
    static bool exit = false;
    static IPEndPoint remoteEP;
    static IPEndPoint remoteUserRequestEP;
    static IPEndPoint localEP;
    static IPEndPoint userRequestListen;

    static Socket listen;
    static Socket send;

    static Thread listenThread;
    static Thread sendThread;
    static void Main(string[] args)
    {
        Console.WriteLine("Message Client");
        start();

    }
    static void start()
    {
      server_ip = input("Please Enter your Server I.P.");
        remoteUserRequestEP = new IPEndPoint(IPAddress.Parse(server_ip), 1300);
        ip = input("Enter your local IPv4 Address");
        desc = input("Enter a short description");
        ign = input("Enter a name to represent yourself");
        localEP = new IPEndPoint(IPAddress.Parse(ip), 11000);
        userRequestListen = new IPEndPoint(IPAddress.Parse(ip), 1300);


        listenThread = new Thread(listening);
        sendThread = new Thread(createSend);

        listenThread.Start();
        sendThread.Start();
    }
    static String input(String inputText)
    {
        Console.WriteLine(inputText);
        return Console.ReadLine();
    }

    static void listening()
    {
     listen = new Socket(AddressFamily.InterNetwork,
        SocketType.Stream, ProtocolType.Tcp);
        String data;

        byte[] bytes;

        try
        {
            listen.Bind(localEP);
            listen.Listen(1);

            while (exit == false)
            {

                Socket handler = listen.Accept();
                data = null;

                while (true)
                {
                    bytes = new byte[1024];
                    int bytesRec = handler.Receive(bytes);
                    data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
                    if (data.IndexOf("<!EOM>") > -1 )
                    {
                      string  finalMSG = data.Replace("<!EOM>", null);
                        Console.WriteLine(finalMSG);
                        break;
                    }
                }


            }

        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }




    }
    static void requestAcesss()
    {
        byte[] msg = new byte[1024];
        msg = Encoding.ASCII.GetBytes(string.Format("!au|name:{0}|ipaddr:{1}|desc:{2}|<!EOM>", ign, ip, desc));
        Socket usrRequest = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        usrRequest.Bind(userRequestListen);
        usrRequest.Connect(userRequestListen);
        usrRequest.Send(msg);

        try {
            while (connected == false)
            {


               Socket handler = usrRequest.Accept();
                string value = null;

                while (true)
                {
                    byte[] bytes = new byte[1024];
                    int bytesRec = handler.Receive(bytes);
                    value += Encoding.ASCII.GetString(bytes, 0, bytesRec);

                    if (value.IndexOf("<!EOM>") > -1)
                    {
                        String[] raw = value.Split(new string[] { "<!PORT>" }, StringSplitOptions.None);
                        port =  Int32.Parse(raw[1]);
                        remoteEP = new IPEndPoint(IPAddress.Parse(server_ip), port);
                        localEP = new IPEndPoint(IPAddress.Parse(ip), port);
                        Console.WriteLine(port);
                        connected = true;
                        startServices();

                    }
                    break;
                }



            }
        }

        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

    static void createSend()
    {
        byte[] msg = new byte[1024];
        send = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        while(exit == false)
        {
            string raw = Console.ReadLine();
            if (raw == "exit")
            {
                exit = true;
                listenThread.Abort();
                sendThread.Abort();

                stop();
                break;
            }

            string finalmsg = string.Format( raw + "<!META>name:{0}<!META><!EOM>", ign);
            send.Bind(localEP);
            msg = Encoding.ASCII.GetBytes(finalmsg);
            send.Send(msg);



        }
        send.Shutdown(SocketShutdown.Both);
        send.Close();
    }
    static void startServices()
    {
            listenThread.Start();
            sendThread.Start();
    }
    static void stop()
    {
        Console.WriteLine("Press any key to terminate");
        Console.ReadLine();
    }
}

套接字不会被使用两次,线程也不会启动两次。

【问题讨论】:

标签: c# sockets logic


【解决方案1】:

遇到同样的错误,我来寻找答案。终于自己找到了: 如果您没有很好地停止它,该进程的早期实例可能仍在运行,例如仅使用 Ctrl+C。

【讨论】: