Java 服务器套接字响应

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20554220/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 02:46:22  来源:igfitidea点击:

Java Server Socket Response

javasocketsclientserversocket

提问by Hyman Carlin

I'm trying to create a simple client/server socket communication application (chat client). I've spent countless hours looking on how to fix this with still no luck, I can send the message to the server but I'm stuck with sending the message back from the server to the client.

我正在尝试创建一个简单的客户端/服务器套接字通信应用程序(聊天客户端)。我花了无数个小时寻找如何解决这个问题,但仍然没有运气,我可以将消息发送到服务器,但我坚持将消息从服​​务器发送回客户端。

I believe the issue is how I'm getting the message from the server after it's sent back, I deleted what I had which was an InputStreamReader which I couldn't get to work.

我相信问题是我如何在发回后从服务器获取消息,我删除了我无法工作的 InputStreamReader 。

(I apologize in advance for the sloppy code)

(我为草率的代码提前道歉)

Server.java

服务器端.java

public class Server extends Thread {
@SuppressWarnings("unused")
private static Socket socket;
static int port = 1337;
static ObjectOutputStream output;

@SuppressWarnings("resource")
public static void main(String[] args) throws IOException{  
    ServerSocket ss = new ServerSocket(port);
    System.out.println("Server started on port: " + port);
    while(!Thread.interrupted()){
        try {  
            Socket clientSocket = ss.accept();
            DataInputStream dis = new DataInputStream(clientSocket.getInputStream()); 
            PrintStream output = new PrintStream(clientSocket.getOutputStream());
            String str = (String)dis.readUTF();
            String[] split = str.split("-");
            String subStringUsername = split[0];
            String subStringMessage = split[1];
            Date date = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("h:mm:ss a");
            String formattedTimestamp = sdf.format(date);
            System.out.println("Message from " + subStringUsername + ": " + subStringMessage + " - at " + formattedTimestamp);
            output.flush();

            output.println("Message received! Hello client!");
            System.out.println("Reply sent");
            output.flush();

            //TODO create new thread handle new users instead of Thread sleep
            //TODO chat commands and user ID / can't be existing user

            Thread.sleep(500);
        }
        catch(Exception e){
            System.out.println(e);
        } 
    }
}

getMessage.java

获取消息

public class GetMessage extends Thread {    
    public void run(){
        while(true) {
            InputStreamReader be = new InputStreamReader();
        }
    }
}

This is what I have left of the getMessage class as I deleted everything in frustration, I'm running getMessage as a thread which I don't know is the best way or not. I've tried 10's of methods to get the message from the server with still not luck, if someone could point me in the right direction I would be greatly appreciative.

这是我在 getMessage 类中留下的东西,因为我沮丧地删除了所有内容,我正在将 getMessage 作为一个线程运行,我不知道这是不是最好的方法。我已经尝试了 10 种方法来从服务器获取消息,但仍然不走运,如果有人能指出我正确的方向,我将不胜感激。

采纳答案by robbmj

readUTF blocks until it receives end of input, and should only be reading data that passed through the writeUTF method.

readUTF 阻塞直到它接收到输入结束,并且应该只读取通过 writeUTF 方法传递的数据。

reference: for a more complete discussion.

参考:更完整的讨论。

readUTF() causing Android app to hang

readUTF() 导致 Android 应用程序挂起

Also check out the docs

还要查看文档

you will probably want to replace

你可能想要更换

DataInputStream dis = new DataInputStream(clientSocket.getInputStream());

with

 BufferedReader reader = new BufferedReader(
        new InputStreamReader(clientSocket.getInputStream()));

and

 dis.readUTF();

with

String str = reader.readLine();

or, if you are not using new lines to mark the end of a message

或者,如果您没有使用新行来标记消息的结尾

char[] buffer = new char[1024];
int read = 0;
StringBuilder sb = new StringBuilder();

while ((read = reader.read(buffer, 0, buffer.length)) > 0) {
    sb.append(buffer, 0, read);
    // conduct some test that when passes marks the end of message, then break;
}
reader.close();

String str = sb.toString().trim();

回答by Ashish

please put output.close() after the flush method or once you are done flushing the out stream.

请把 output.close() 放在flush方法之后,或者在你完成flush out流之后。

Also I would use something like this to implement a chat application. It also uses Java Swings to draw client and server window. Use it as a reference. The formatting might be little sloppy here.

另外我会使用这样的东西来实现一个聊天应用程序。它还使用 Java Swings 来绘制客户端和服务器窗口。将其用作参考。这里的格式可能有点草率。

This is my client code:

这是我的客户端代码:

public class Client
{
private Socket s;
private Scanner input;
private PrintWriter output;
private ChatFrame frame;
static String s1;

public Client( int port ) throws IOException 
{
    s = new Socket( "127.0.0.1", port );
    input = new Scanner(s.getInputStream());
    output = new PrintWriter(s.getOutputStream());

}
public static void main(String[] args) throws java.io.IOException
{
    System.out.println("Enter The port No. :");
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String s = br.readLine();
    System.out.println("Enter Name : ");
    br = new BufferedReader(new InputStreamReader(System.in));
    s1 = br.readLine();
    final Client client = new Client(Integer.parseInt(s));
    EventQueue.invokeLater(new Runnable() 
       {
            public void run() {
            client.frame = new ChatFrame(client.output,s1);

            }
        });

    String ClientChat = "";
    while(true) 
    {
        if(client.input.hasNextLine()) 
        {
            ClientChat = client.input.nextLine();
            client.frame.Chat(ClientChat);                                
        }
    }
   }
 }
class ChatFrame 
{
    JFrame jf;
    JPanel jp;
    JTextArea jta1,jta2;
    JButton jb;
    public ChatFrame(final PrintWriter output, final String Name) 
       {
            jf = new JFrame();
            jf.setTitle(Name);
            jf.setSize(800,600);
            jp = new JPanel();
            jp.setBounds(0,0,800,600);
            jta1 = new JTextArea();
            jta2 = new JTextArea();
            jta1.setBounds(20,10,760,390);
                 jta1.setBorder(BorderFactory.createLineBorder(Color.BLACK,2));
            jta2.setBounds(20,420,550,100);
            jta2.setBorder(BorderFactory.createLineBorder(Color.BLACK,2));
            jb = new JButton("SEND");
            jb.setBounds(590,420,190,100);
            jp.add(jb);
            jp.add(jta1);
            jp.add(jta2);
            jp.setLayout(null);


    ActionListener Action = new ActionListener() {
    public void actionPerformed(ActionEvent e) {
            String str = Name + " : " + jta2.getText();
            if(str.length() > 0) 
                {
                    output.println(str);
                    output.flush();
                    jta2.setText("");
                    jta2.grabFocus();
                }
        }
    };
    jb.addActionListener(Action);
    jf.add(jp);
    jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    jf.setVisible(true);
    }
    public void Chat(String MSG) 
    {
            jta1.append(MSG + "\n");
            StringTokenizer st = new StringTokenizer(MSG,":");
            int flag = 0;
            if(st.hasMoreElements())
               {
                    if(st.nextElement() == "bye" && flag == 0)
                       {
                            jf.setVisible(false);
                            jf.validate();
                            System.exit(0);
                        }
                    flag = 1;
                }
       }
}

and here is my server code:

这是我的服务器代码:

public class MyServer
 {
    Hashtable<Socket,PrintWriter> output = new Hashtable<Socket,PrintWriter>();
    ServerSocket ss;
    Socket s;
    public void MakeConn()
       {
            try
               {
                    ss = new ServerSocket(1001);
                    while(true)
                    {
                        s = ss.accept();
                        System.out.println("Connection from " + s);
                        PrintWriter outMsg = new PrintWriter(s.getOutputStream());
                        output.put(s,outMsg);
                        new ServerThread(this,s);
                    }
                }
            catch(Exception E)
               {

                }
        }

    public void tellEveryOne(String msg) 
    {
        synchronized(output) 
        {
            Enumeration keys = output.keys();
            while ( keys.hasMoreElements() )
               {
                    Socket ss = (Socket)keys.nextElement();
                    PrintWriter outMsg = output.get( ss );
                    outMsg.println(msg);
                    outMsg.flush();
                }
        }
    }
    public void ConnectionClose(Socket socket) 
    {
        try 
           {
                output.remove(socket);
                socket.close();
           }
        catch(IOException e) 
           {

           }
    }
public static void main(String[] args)
{
    MyServer ms = new MyServer();
    ms.MakeConn();
}
}

class ServerThread extends Thread
   {
        MyServer server;
        Socket socket;

        public ServerThread(MyServer server, Socket socket) 
           {
                this.server = server;
                this.socket = socket;
                this.start();
            }
        public void run() 
           {
                try 
                   {
                        Scanner input = new Scanner(socket.getInputStream());
                        String inMsg;
                        String ByeMsg;
                        while(true) 
                           {
                                  if(input.hasNextLine()) 
                                   {
                                            inMsg = input.nextLine();
                                         System.out.println(inMsg);
                                         StringTokenizer st = new StringTokenizer(inMsg,":");
                                        int flag = 0;
                                         if(st.hasMoreElements())
                                           {
                                                if(st.nextElement() == "bye" && flag == 0)
                                                   {
                                                         input.close();
                                                         socket.close();
                                                         break;
                                                     }
                                                flag = 1;
                                            }
                                          server.tellEveryOne(inMsg);
                                    }
                            }
                    }
                catch(IOException E)
                   {
                    }
                finally 
                   {
                        server.ConnectionClose(socket);
                   }
            }

    }