如何从服务器向列表中的多个客户端发送消息

时间:2016-08-31 05:03:17

标签: java sockets network-programming bind serversocket

我曾尝试将以下代码作为服务器向ip为列表的客户端发送消息mSession

for (MSession mSession : mSessions)
{
   System.out.println("Inside for each");
   System.out.println("IP TEST : " + mSession.getRemote_Addr());
   ServerSocket srvr = new ServerSocket(1324, 5, InetAddress.getByName(mSession.getRemote_Addr()));
   Socket skt = srvr.accept();
   System.out.println("IP1:" + InetAddress.getByName(mSession.getRemote_Host()));
   System.out.println("IP2:" + skt.getInetAddress().getHostAddress());           
   System.out.print("Server has connected!\n");
   PrintWriter out = new PrintWriter(skt.getOutputStream(), true);
   System.out.print("Sending string: '" + data + "'\n");
   out.print(data);
   out.close();
   skt.close();
   srvr.close();                                         
}

客户端代码:

InetAddress ip = InetAddress.getByName(host[0]);
System.out.println("IP SERVER : " + ip);
Socket skt = new Socket(ip, 1324);// Ip address of server
in = new BufferedReader(new InputStreamReader(skt.getInputStream()));
System.out.print("Received string: ");

while (!in.ready()) {}
data = in.readLine();
System.out.println(in.readLine());

System.out.print("'\n");
Popupapp app = new Popupapp();
app.fdis(data);
in.close();
skt.close();

我得到的bindexception无法分配请求的地址:JVM_Bind 我尝试过其他端口,但异常保持不变 我曾尝试过端口8080,8089,8086,8009,1234,8242,8006

请帮我解决这个问题。

我曾试过这个简单的程序并且显示相同的异常

public class ServerSide extends Thread{

public void run()
{
    while(true)
    {
        String data = "Recieved new notification";
        try {

             ServerSocket srvr = new ServerSocket(1234, 5, InetAddress.getByName("192.168.168.40"));
             Socket skt = srvr.accept();

             skt.getInputStream();

             System.out.print("Server has connected!\n");
             PrintWriter out = new PrintWriter(skt.getOutputStream(), true);
             System.out.print("Sending string: '" + data + "'\n");
             out.print(data);
             out.close();
             skt.close();
             srvr.close();
             Thread.sleep(500);



      }

   catch(Exception e) {
      System.out.print("Whoops! It didn't work!\n" + e);
      try {
        Thread.sleep(1000);
    } catch (InterruptedException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
   }

}
}

1 个答案:

答案 0 :(得分:2)

原因是你在foreach循环中创建了服务器套接字。因此,在第一次处理第一个客户端并且第一次创建serversocket之后,此代码再次尝试在下一个客户端处理中在同一端口上创建另一个serversocket,从而导致绑定异常。 / p>

解决方案是在循环之前创建一个单独的serversocket,它将继续接受foreach循环内的客户端。如下所示:

ServerSocket srvr = new ServerSocket(1324, 5, InetAddress.getByName(mSession.getRemote_Addr()));
for (MSession mSession : mSessions)
              {
                  System.out.println("Inside for each");
                  System.out.println("IP TEST : " + mSession.getRemote_Addr());
                  // start accepting client-requests                     
                  Socket skt = srvr.accept();
                  System.out.println("IP1:" + InetAddress.getByName(mSession.getRemote_Host()));
                  System.out.println("IP2:" + skt.getInetAddress().getHostAddress());            
                  System.out.print("Server has connected!\n");
                  PrintWriter out = new PrintWriter(skt.getOutputStream(), true);
                  System.out.print("Sending string: '" + data + "'\n");
                  out.print(data);
                  out.close();
                  skt.close();                                     
              }
                // finally close the server-socket!                
                  srvr.close(); 

根据您的编辑:

您再次在循环内创建ServerSocket! DON' T !!! * 在构造函数(或其他方法)中执行此操作。

public class ServerSide extends Thread{

public ServerSide(){
ServerSocket srvr = new ServerSocket(1234, 5, InetAddress.getByName("192.168.168.40"));
}
public void run()
{
while(true)
{
    String data = "Recieved new notification";
    try {             
         Socket skt = srvr.accept();
         skt.getInputStream();
         System.out.print("Server has connected!\n");
         PrintWriter out = new PrintWriter(skt.getOutputStream(), true);
         System.out.print("Sending string: '" + data + "'\n");
         out.print(data);
         out.close();
         skt.close();
         srvr.close();
         Thread.sleep(500);
  }
catch(Exception e) {
  System.out.print("Whoops! It didn't work!\n" + e);
  try {
    Thread.sleep(1000);
} catch (InterruptedException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
}
}

现在,从服务器端的main方法调用它,如:

new ServerSide().start();