服务器无法将消息发送到客户端(Java线程套接字编程) [英] Server unable to send messages to client (java thread socket programming)

查看:79
本文介绍了服务器无法将消息发送到客户端(Java线程套接字编程)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

将在存在"-l"的情况下运行主功能文件,如果不存在"-l",则将决定其是作为服务器还是作为客户端.

运行服务器的命令参数是

java DirectMessengerCombined -l 3000

运行客户端的命令参数是

java DirectMessengerCombined 3000

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

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

该屏幕截图的问题是未将消息您好,我是服务器的客户端"发送给客户端.

服务器代码:

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

在此示例中,输入和输出在同一线程中处理,如果要同时进行读写,请提交两项任务,一项任务在输入项上进行,一项任务在输出项上进行.重要提示:仅在接受连接后 才能获得套接字.

如果您想彼此进行线程通信,则可以使用共享对象(即消息队列)来完成.但是此数据结构必须是 threadsafe ,而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();
         }
    });
 }

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

There are three files (the main function file, the server file, and the client file)

The main function file will be run where the presence of "-l" determines whether it will behave as a server or a client if "-l" is not present.

The command arguments to run the server is

java DirectMessengerCombined -l 3000

The command arguments to run the client is

java DirectMessengerCombined 3000

There are four threads (one for receiving messages on client side, one for sending messages on client side, one for receiving messages on server side, one for sending messages on server side)

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

The problem with the screenshot is that the message "Hello client I am server" was not sent across to the client.

Code of 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();










    }
}

Code of client:

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

Code of main function file:

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

}

My question is how to make the server and client both able to continuously send and receive messages to each other (sending works on client side, but receiving does not work)

解决方案

A good way is to separate accepting a connection and operating on a connection, which is what most servers do.

For example, you accept incoming connections on the main thread and operate on the connection in a thread pool, using an executor service:

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

In this example input and output is processed in the same thread, if you want to concurrently read and write, submit two tasks, one operating on the input, one of the output. Important: you only get your socket after the connection has been accepted.

If you want to thread communicate with each other, you can do this with a shared object, i.e. a message queue. But this datastructure must be threadsafe, and the JDK provides a lot of those datastructure:

  • ConcurrentHashMap
  • CopyOnWriteArrayList
  • ConcurrentSkipListSet
  • ...

for example

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

And basically the same for the client, except that you dont accept a connection but open one

这篇关于服务器无法将消息发送到客户端(Java线程套接字编程)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆