服务器无法向客户端发送消息(java线程套接字编程)

时间:2017-05-10 15:10:49

标签: java multithreading sockets

有三个文件(主函数文件,服务器文件和客户端文件)

将运行主函数文件,其中“-l”的存在确定如果“-l”不存在,它将表现为服务器还是客户端。

运行服务器的命令参数是

java DirectMessengerCombined -l 3000

运行客户端的命令参数是

java DirectMessengerCombined 3000

有四个线程(一个用于在客户端接收消息,一个用于在客户端发送消息,一个用于在服务器端接收消息,一个用于在服务器端发送消息)

Screenshot of running program (client on right, server on left)

屏幕截图的问题是“客户端我是服务器的客户端”消息未发送到客户端。

服务器代码:

import java.io.*;
import java.net.*;
import java.util.*;

import javax.imageio.IIOException;
//import static java.nio.charset.StandardCharsets.*;
public class DirectMessengerServer
{
    private static Socket socket;
    boolean KeepRunning = true;
    void ServerRun(String[] args) 
    {
        Thread ServerRecieve = new Thread () 
        {
            public void run ()
            {   
                System.out.println("Server recieve thread is now running");
                try
                {
                    System.out.println("Try block begins..");
                    int port_number1= Integer.valueOf(args[1]);
                    System.out.println("Port number is: " + port_number1);
                    ServerSocket serverSocket = new ServerSocket(port_number1);
                    //SocketAddress addr = new InetSocketAddress(address, port_number1);
                    System.out.println( "Listening for connections on port: " + ( port_number1 ) );

                    while(KeepRunning)
                    {
                        //Reading the message from the client

                        socket = serverSocket.accept();    
                        InputStream is = socket.getInputStream();
                        InputStreamReader isr = new InputStreamReader(is);
                        BufferedReader br = new BufferedReader(isr);
                        String MessageFromClient = br.readLine();
                        System.out.println("Message received from client: "+ MessageFromClient);


                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                finally
                {
                }
            }
        };ServerRecieve.start();

          Thread ServerSend = new Thread () 
            {
                public void run ()
                {   
                    System.out.println("Server sending thread is now running");
                    try
                    {         

                        //Send the message to the server
                        OutputStream os = socket.getOutputStream();
                        OutputStreamWriter osw = new OutputStreamWriter(os);
                        BufferedWriter bw = new BufferedWriter(osw);

                        //creating message to send from standard input
                        String newmessage = "";
                        try 
                        {
                            // input the message from standard input
                            BufferedReader input= new BufferedReader( 
                            new InputStreamReader(System.in));
                            String line = "";

                            line= input.readLine(); 
                                newmessage += line + " ";


                        }
                        catch ( Exception e )
                        {
                            System.out.println( e.getMessage() );
                        }
                        String sendMessage = newmessage;
                        bw.write(sendMessage + "\n");
                        bw.flush();
                        System.out.println("Message sent to client: "+sendMessage);

                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    finally
                    {

                    }
                }
            };ServerSend.start();










    }
}

客户代码:

import java.io.*;
import java.net.*;
import java.util.*;
import static java.nio.charset.StandardCharsets.*;
public class DirectMessengerClient
{
    boolean KeepRunning = true;
    private static Socket socket;
    //static String[] arguments;
    //public static void main(String[] args)
    //{
    //  arguments = args;
    //}
    public DirectMessengerClient()
    {

        //System.out.println("test.");

    }
    public void ClientRun(String[] args)
    {

        Thread ClientSend = new Thread ()
        {
          public void run()
          {   
                System.out.println("Client sending thread is now running");

                    try
                    {
                            System.out.println("Try block begins..");
                            String port_number1= args[0];
                            System.out.println("Port number is: " + port_number1);
                            int port = Integer.valueOf(port_number1);
                            System.out.println("Listening for connections..");
                            System.out.println( "Listening on port: " + port_number1 );
                            while(KeepRunning)
                            {

                                String host = "localhost";
                                InetAddress address = InetAddress.getByName(host);
                                socket = new Socket(address, port);


                                //Send the message to the server
                                OutputStream os = socket.getOutputStream();
                                OutputStreamWriter osw = new OutputStreamWriter(os);
                                BufferedWriter bw = new BufferedWriter(osw);

                                //creating message to send from standard input
                                String newmessage = "";
                                try 
                                {
                                    // input the message from standard input
                                    BufferedReader input= new BufferedReader( 
                                    new InputStreamReader(System.in));
                                    String line = "";

                                    line= input.readLine(); 
                                        newmessage += line + " ";


                                }
                                catch ( Exception e )
                                {
                                    System.out.println( e.getMessage() );
                                }
                                String sendMessage = newmessage;
                                bw.write(sendMessage + "\n");
                                bw.flush();
                                System.out.println("Message sent to server: "+sendMessage);
                            }
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    finally
                    {

                    }

                    //finally
                //  {
                    //}


          }
        }; ClientSend.start();

        Thread ClientRecieve = new Thread ()
        {
          public void run()
          {  
              while(KeepRunning)
              {
                  try
                  {

                                System.out.println("Client Reieving thread is now running");
                                //Get the return message from the server
                                InputStream is = socket.getInputStream();
                                InputStreamReader isr = new InputStreamReader(is);
                                BufferedReader br = new BufferedReader(isr);
                                String MessageFromServer = br.readLine();
                                System.out.println("Message received from server: " + MessageFromServer);
                                 if(MessageFromServer.equals(""))
                                 {
                                    KeepRunning=false;
                                    System.out.println("Shutting down");
                                    System.exit(0);
                                    socket.close();
                                 }
                                 if(MessageFromServer.equals(null))
                                 {
                                    KeepRunning=false;
                                    System.out.println("Shutting down");
                                    System.exit(0);
                                    socket.close();
                                 }
                                 if(MessageFromServer=="")
                                 {
                                    KeepRunning=false;
                                    System.out.println("Shutting down");
                                    System.exit(0);
                                    socket.close();
                                 }
                                 if(MessageFromServer==null)
                                 {
                                    KeepRunning=false;
                                    System.out.println("Shutting down");
                                    System.exit(0);
                                    socket.close();
                                 }
                                 if(MessageFromServer=="\n")
                                 {
                                    KeepRunning=false;
                                    System.out.println("Shutting down");
                                    System.exit(0);
                                    socket.close();
                                 }
                  } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                  finally
                  {

                  }
              }
          }
        };ClientRecieve.start();
    }
}

主要功能文件代码:

public class DirectMessengerCombined
{
    public static void main(String[] args)
    {
        DirectMessengerClient Client1 = new DirectMessengerClient();
        DirectMessengerServer Server1 = new DirectMessengerServer();
          for (int i = 0; i < args.length; i++)
          {
                if(!args[0].equals("-l"))
                {
                    Client1.ClientRun(args);
                }
                switch (args[0].charAt(0))
                {
                    case '-':
                    if(args[0].equals("-l"))
                    {   
                        Server1.ServerRun(args);
                    }

                }
           i=args.length + 20;
          } 
    }

}

我的问题是如何使服务器和客户端都能够连续发送和接收消息(在客户端发送工作,但接收不起作用)

1 个答案:

答案 0 :(得分:0)

一种好方法是分离接受连接和操作连接,这是大多数服务器所做的。

例如,您接受主线程上的传入连接,并使用执行程序服务对线程池中的连接进行操作:

    AtomicBoolean running = new AtomicBoolean();
    ExecutorService pool = Executors.newFixedThreadPool(10;
    ServerSocket listen = new ServerSocket(11000);
    while(running.get()){
        Socket socket = listen.accept();
        pool.submit(() -> {

            try(InputStream is = socket.getInputStream();
                OutputStream os = socket.getOutputStream()){

               //put I/O logic here


            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }

在此示例中,输入和输出在同一个线程中处理,如果要同时读写,则提交两个任务,一个操作输入,另一个输出。重要提示:只有在接受连接后才能获得套接字

如果要彼此进行线程通信,可以使用共享对象(即消息队列)执行此操作。但是这个数据结构必须是线程安全,而JDK提供了很多这样的数据结构:

  • 的ConcurrentHashMap
  • 的CopyOnWriteArrayList
  • ConcurrentSkipListSet
  • ...

例如

 final ConcurrentLinkedDeque<String> queue = new ConcurrentLinkedDeque<>();

 while(running.get()){
    Socket socket = listen.accept();
    pool.submit(() -> {

        try(BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()))){
            while(socket.isConnected()){
                queue.push(reader.readLine());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    });
    pool.submit(() -> {
        try(OutputStream os = socket.getOutputStream()){
            if(!queue.isEmpty()){
                 os.write(queue.pop().getBytes());
            }
         } catch (IOException e) {
            e.printStackTrace();
         }
    });
 }

对于客户来说基本相同,只是你不接受连接而是打开一个