如何使用java套接字在服务器和客户端之间进行双向通信?

问题描述 投票:0回答:1

如何使用java套接字在服务器和客户端之间进行双向通信?我在 Windows 下使用 JDK 17.0.7。

服务器代码

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class MyServer {

    ServerSocket myServerSocket;
    MyTestClient[] myTestClients = new MyTestClient[1];
    
    /*
     * CAN NOT Access inncer class
     * Just create an object, execute from object, 
     * and create inner object
     */
    public static void main(String[] args) {
        MyServer myServer = new MyServer();
        myServer.start();
    }
    
    public void start() {
        // TODO Auto-generated method stub
        try {
            myServerSocket = new ServerSocket(54321);
            Socket socketClient;
            for (int i=0;i<1;i++) {
                socketClient = myServerSocket.accept();
                socketClient.setKeepAlive(true);
                MyTestClient myTestClient = new MyTestClient("Test", socketClient);
                myTestClients[i]=myTestClient;
            }
            boolean isLoop = true;
            int i=0;
            while (isLoop) {                

                String msg = "Hello "+i;
                System.out.println("Send to client: "+msg); // debug
                myTestClients[0].sendMsg(msg);
                
                int sleepInt = 100;
                System.out.println("Sleep "+sleepInt); // debug
                try {
                    Thread.sleep(sleepInt);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                        
                String msgClient = myTestClients[0].receiveMsg();
                System.out.println(msgClient); // debug

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


    public class MyTestClient {
        public String name;
        public Socket clientSocket;
        OutputStream myOutputStream;
        PrintWriter myPW;
        BufferedReader myBR;
        
        public MyTestClient(String name, Socket clientSocket) throws IOException {
            this.name = name;
            this.clientSocket = clientSocket;
            myOutputStream = clientSocket.getOutputStream();
            myPW = new PrintWriter(myOutputStream);
            myBR = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

        }
        
        public void sendMsg(String msg) throws IOException {
            myPW.println(msg);
            myPW.flush();
        }
        
        public String receiveMsg() throws IOException {
            String str = myBR.readLine();
            StringBuffer sb = new StringBuffer();
            while(str!=null) {
                if (str.equals("END")) {
                    return str;
                }
                System.out.println(str);
                sb.append(str);
                str = myBR.readLine(); 
            }
            return sb.toString();
            
        }
    }

}

客户端代码

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

public class MyClient {

    InetAddress myServer;
    int myPort = 54321;
    Socket mySocket;
    
    OutputStream myOutputStream;
    PrintWriter myPW;
    BufferedReader myBR;
    
    /*
     * CAN NOT Access inncer class
     * Just create an object, execute from object, 
     * and create inner object
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MyClient myClient = new MyClient();
        myClient.start();
    }

    public void start() {
        try {
            myServer = InetAddress.getLocalHost();
            mySocket= new Socket(myServer,myPort);
            myOutputStream = mySocket.getOutputStream();
            myPW = new PrintWriter(myOutputStream);
            myBR = new BufferedReader(new InputStreamReader(mySocket.getInputStream()));

            for (int i=0;i<5;i++) {
                
                String msg = receiveMsg();
                System.out.println(msg); // debug

                int sleetInt = 1000;
                try {
                    Thread.sleep(sleetInt);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                msg = msg+" from Client";
                System.out.println(msg); // debug
                sendMsg(msg);

            }
            mySocket.close();
            
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    private void sendMsg(String msg) throws IOException {

        myPW.println(msg);
        myPW.flush();
    }
    
    private String receiveMsg() throws IOException {
        String str = myBR.readLine();
        StringBuffer sb = new StringBuffer();
        while(str!=null) {
            if (str.equals("END")) {
                return str;
            }
            System.out.println(str);
            sb.append(str);
            str = myBR.readLine(); 
        }
        return sb.toString();
        
    }

}

服务器中的结果

>java MyServer
Send to client: Hello 0
Sleep 1000

客户端结果

>java MyClient
Hello 0

它没有按预期循环 5 次。谁能帮我看看代码哪里错了?我需要在客户端创建ServerSocket来接受来自服务器的命令吗?谢谢你

我期望服务器中的输出(调试):

Send to client: Hello 0
Hello 0 from Client
Send to client: Hello 1
Hello 1 from Client
Send to client: Hello 2
Hello 2 from Client
...

我期望客户端中的输出(调试):

Hello 0
Hello 0 from Client
Hello 1
Hello 1 from Client
Hello 2
Hello 2 from Client
...
java sockets serversocket
1个回答
0
投票

为了实现2路连接,我们需要在客户端创建套接字。如果局域网游戏连接有回合基地,我们可以控制哪个客户端应该回合。

这是服务器的代码:

package com.dedetok.lancardgame.test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class MyServer2 {
    int serverPort = 54321;
    ServerSocket serverSocket;
    int clientPort = 54322;
    Socket clientSocket;
    InetAddress clientInetAddress;
    
    Socket clientConnectionSocket;
    OutputStream myOutputStream;
    PrintWriter myPW;
    BufferedReader myBR;

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MyServer2 myServer2 = new MyServer2();
        
        myServer2.start();
    }
    
    public void start() {
        try {
            System.out.println("Start server"); // debug
            serverSocket = new ServerSocket(serverPort);
            boolean isLoop = true;
            while (isLoop) {
                clientConnectionSocket = serverSocket.accept();
                clientInetAddress = clientConnectionSocket.getInetAddress();
                myOutputStream = clientConnectionSocket.getOutputStream();
                //myPW = new PrintWriter(myOutputStream);
                //myPW = new PrintWriter(myOutputStream, true);
                myBR = new BufferedReader(new InputStreamReader(clientConnectionSocket.getInputStream()));
                
                StringBuffer sb = new StringBuffer();
                String stringFromClient = myBR.readLine();
                while (stringFromClient!=null) {
                    sb.append(stringFromClient);
                    stringFromClient = myBR.readLine();
                }
                String stringClient = sb.toString();
                System.out.println(stringClient); // debug
                myBR.close();
                //myPW.close();
                
                if (stringClient.equals("END")) {
                    stringServer = stringClient;
                    myServerRun.run();
                    isLoop = false;
                    
                } else {
                    stringServer = "From Server: "+stringClient;
                    myServerRun.run();
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    
                }

                
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    String stringServer;
    Runnable myServerRun = new Runnable() {
        
        @Override
        public void run() {
            try {
                // TODO Auto-generated method stub
                clientSocket = new Socket(clientInetAddress, clientPort);
                myOutputStream = clientSocket.getOutputStream();
                myPW = new PrintWriter(myOutputStream);
                //myPW = new PrintWriter(myOutputStream, true);
                //myBR = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                 
                myPW.println(stringServer);
                myPW.flush();
                myPW.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }   
    };

}

客户

package com.dedetok.lancardgame.test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class MyClient2 {
    int serverPort = 54321;
    Socket serverSocket;
    int clientPort = 54322;
    ServerSocket clientSocket;
    InetAddress serverInetAddress;
    
    OutputStream myOutputStream;
    PrintWriter myPW;
    BufferedReader myBR;
    
    int myCounter = 0;
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MyClient2 myClient2 = new MyClient2();
        
        myClient2.start();
    }
    
    public void start() {
        try {

            serverInetAddress = InetAddress.getLocalHost(); // the same host
            myClientRun.run();
            clientSocket = new ServerSocket(54322);
            boolean isLoop = true;
            while (isLoop) {
                serverSocket = clientSocket.accept();
                serverInetAddress = serverSocket.getInetAddress();
                //myPW = new PrintWriter(myOutputStream);
                //myPW = new PrintWriter(myOutputStream, true);
                myBR = new BufferedReader(new InputStreamReader(serverSocket.getInputStream()));
                
                StringBuffer sb = new StringBuffer();
                String stringFromServer = myBR.readLine();
                while (stringFromServer!=null) {
                    sb.append(stringFromServer);
                    stringFromServer = myBR.readLine();
                }
                String stringServer = sb.toString();
                System.out.println(stringServer); // debug
                myBR.close();
                
                if (!stringServer.equals("END")) {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    myClientRun.run();
                } else {
                    isLoop = false;
                    System.out.println("myCounter: "+myCounter); // debug
                }
                
                
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    

    Runnable myClientRun = new Runnable() {
        
        @Override
        public void run() {
            try {

                // TODO Auto-generated method stub
                serverSocket = new Socket(serverInetAddress, serverPort);
                myOutputStream = serverSocket.getOutputStream();
                myPW = new PrintWriter(myOutputStream);
                //myPW = new PrintWriter(myOutputStream, true);
                //myBR = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                String stringClient = "Hello #: "+myCounter;
                if (myCounter==5) {
                    stringClient = "END";
                }
                myPW.println(stringClient);
                myPW.flush();
                myPW.close();
                
                myCounter++;
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }   
    };

}

客户端可以使用与服务器端口相同的端口来侦听传入的端口,只要它运行在具有不同 IP 的单独设备上即可。

© www.soinside.com 2019 - 2024. All rights reserved.