繁体   English   中英

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

[英]Server unable to send messages to client (java thread socket programming)

一共有三个文件(主要功能文件,服务器文件和客户端文件)

如果“ -l”不存在,则将在存在“ -l”的地方运行主功能文件,以决定它是作为服务器还是作为客户端。

运行服务器的命令参数是

java DirectMessengerCombined -l 3000

运行客户端的命令参数是

java DirectMessengerCombined 3000

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

正在运行的程序的屏幕截图(客户端在右侧,服务器在左侧)

屏幕截图的问题在于,消息“ Hello client I are server”没有发送到客户端。

服务器代码:

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;
          } 
    }

}

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

一个好的方法是将接受连接和对连接进行操作分开,这是大多数服务器所做的。

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

    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();
         }
    });
 }

与客户端基本相同,除了您不接受连接而是打开一个连接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM