web-dev-qa-db-ja.com

ソケットを使用してデータを送受信する

ソケットを使用して、Androidアプリケーション(クライアント)とJavaバックエンドサーバー。クライアントから、毎回2つのデータ変数を送信したい。サーバーと通信します。

1)ある種のメッセージ(インターフェースを介してユーザーが定義)

2)メッセージの言語(インターフェースを介してユーザーが定義)

サーバーがそれぞれを個別のエンティティとして解釈するようにこれらを送信するにはどうすればよいですか?

サーバー側でデータを読み取り、適切な結論を出した後、クライアントに単一のメッセージを返したいと思います。 (これで大丈夫だと思います)

したがって、2つの質問は、送信される2つの文字列(クライアントからサーバー)がクライアント側で一意であることを確立する方法と、これら2つの文字列をサーバー側で分離する方法です。 (文字列の配列を考えていましたが、これが可能か適切かを確立できませんでした。)

私はいくつかのコードを投稿するつもりでしたが、それがどのように役立つかわかりません。

30
London Student

クライアントとサーバーの対話にTCPソケットを使用していますか?異なるタイプのデータをサーバーに送信し、2つを区別できるようにする1つの方法は、最初のバイトを専用にすることです(または256を超える種類のメッセージがある場合はそれ以上)何らかの種類の識別子として。最初のバイトが1の場合、メッセージA、2の場合、そのメッセージB。これをソケット経由で送信する簡単な方法DataOutputStream/DataInputStreamを使用することです:

クライアント:

Socket socket = ...; // Create and connect the socket
DataOutputStream dOut = new DataOutputStream(socket.getOutputStream());

// Send first message
dOut.writeByte(1);
dOut.writeUTF("This is the first type of message.");
dOut.flush(); // Send off the data

// Send the second message
dOut.writeByte(2);
dOut.writeUTF("This is the second type of message.");
dOut.flush(); // Send off the data

// Send the third message
dOut.writeByte(3);
dOut.writeUTF("This is the third type of message (Part 1).");
dOut.writeUTF("This is the third type of message (Part 2).");
dOut.flush(); // Send off the data

// Send the exit message
dOut.writeByte(-1);
dOut.flush();

dOut.close();

サーバ:

Socket socket = ... // Set up receive socket
DataInputStream dIn = new DataInputStream(socket.getInputStream());

boolean done = false;
while(!done) {
  byte messageType = dIn.readByte();

  switch(messageType)
  {
  case 1: // Type A
    System.out.println("Message A: " + dIn.readUTF());
    break;
  case 2: // Type B
    System.out.println("Message B: " + dIn.readUTF());
    break;
  case 3: // Type C
    System.out.println("Message C [1]: " + dIn.readUTF());
    System.out.println("Message C [2]: " + dIn.readUTF());
    break;
  default:
    done = true;
  }
}

dIn.close();

当然、バイトと文字列(UTF)だけでなく、あらゆる種類のデータを送信できます。

writeUTFは、変更されたUTF-8形式を書き込み、送信する2^16 - 1 = 65535バイトを与える符号なし2バイトエンコード整数の長さインジケーターが先行することに注意してください。これにより、readUTFがエンコードされた文字列の終わりを見つけることができます。独自のレコード構造を決定する場合は、レコードの終わりとタイプが既知であるか、検出可能であることを確認する必要があります。

61
Nick Banks

これを行う最も簡単な方法は、ObjectInput/OutputStreamsでソケットをラップし、シリアル化されたJavaオブジェクトを送信することです。関連するデータを含むクラスを作成でき、心配する必要はありません。バイナリプロトコルの処理の詳細については、各オブジェクトの「メッセージ」を書き込んだ後にオブジェクトストリームをフラッシュするようにしてください。

4
jtahlborn
    //Client

    import Java.io.*;
    import Java.net.*;

    public class Client {
        public static void main(String[] args) {

        String hostname = "localhost";
        int port = 6789;

        // declaration section:
        // clientSocket: our client socket
        // os: output stream
        // is: input stream

            Socket clientSocket = null;  
            DataOutputStream os = null;
            BufferedReader is = null;

        // Initialization section:
        // Try to open a socket on the given port
        // Try to open input and output streams

            try {
                clientSocket = new Socket(hostname, port);
                os = new DataOutputStream(clientSocket.getOutputStream());
                is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            } catch (UnknownHostException e) {
                System.err.println("Don't know about Host: " + hostname);
            } catch (IOException e) {
                System.err.println("Couldn't get I/O for the connection to: " + hostname);
            }

        // If everything has been initialized then we want to write some data
        // to the socket we have opened a connection to on the given port

        if (clientSocket == null || os == null || is == null) {
            System.err.println( "Something is wrong. One variable is null." );
            return;
        }

        try {
            while ( true ) {
            System.out.print( "Enter an integer (0 to stop connection, -1 to stop server): " );
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            String keyboardInput = br.readLine();
            os.writeBytes( keyboardInput + "\n" );

            int n = Integer.parseInt( keyboardInput );
            if ( n == 0 || n == -1 ) {
                break;
            }

            String responseLine = is.readLine();
            System.out.println("Server returns its square as: " + responseLine);
            }

            // clean up:
            // close the output stream
            // close the input stream
            // close the socket

            os.close();
            is.close();
            clientSocket.close();   
        } catch (UnknownHostException e) {
            System.err.println("Trying to connect to unknown Host: " + e);
        } catch (IOException e) {
            System.err.println("IOException:  " + e);
        }
        }           
    }





//Server




import Java.io.*;
import Java.net.*;

public class Server1 {
    public static void main(String args[]) {
    int port = 6789;
    Server1 server = new Server1( port );
    server.startServer();
    }

    // declare a server socket and a client socket for the server

    ServerSocket echoServer = null;
    Socket clientSocket = null;
    int port;

    public Server1( int port ) {
    this.port = port;
    }

    public void stopServer() {
    System.out.println( "Server cleaning up." );
    System.exit(0);
    }

    public void startServer() {
    // Try to open a server socket on the given port
    // Note that we can't choose a port less than 1024 if we are not
    // privileged users (root)

        try {
        echoServer = new ServerSocket(port);
        }
        catch (IOException e) {
        System.out.println(e);
        }   

    System.out.println( "Waiting for connections. Only one connection is allowed." );

    // Create a socket object from the ServerSocket to listen and accept connections.
    // Use Server1Connection to process the connection.

    while ( true ) {
        try {
        clientSocket = echoServer.accept();
        Server1Connection oneconnection = new Server1Connection(clientSocket, this);
        oneconnection.run();
        }   
        catch (IOException e) {
        System.out.println(e);
        }
    }
    }
}

class Server1Connection {
    BufferedReader is;
    PrintStream os;
    Socket clientSocket;
    Server1 server;

    public Server1Connection(Socket clientSocket, Server1 server) {
    this.clientSocket = clientSocket;
    this.server = server;
    System.out.println( "Connection established with: " + clientSocket );
    try {
        is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        os = new PrintStream(clientSocket.getOutputStream());
    } catch (IOException e) {
        System.out.println(e);
    }
    }

    public void run() {
        String line;
    try {
        boolean serverStop = false;

            while (true) {
                line = is.readLine();
        System.out.println( "Received " + line );
                int n = Integer.parseInt(line);
        if ( n == -1 ) {
            serverStop = true;
            break;
        }
        if ( n == 0 ) break;
                os.println("" + n*n ); 
            }

        System.out.println( "Connection closed." );
            is.close();
            os.close();
            clientSocket.close();

        if ( serverStop ) server.stopServer();
    } catch (IOException e) {
        System.out.println(e);
    }
    }
}
2
Utpal Goswami