我使用套接字连接我的Android应用程序(客户端)和Java后端服务器。从客户端我想在每次与服务器通信时发送两个数据变量。
1)某种消息(由用户通过界面定义)
2)消息的语言(由用户通过界面定义)
我如何发送这些内容,以便服务器将每个解释为一个单独的实体?
在服务器端读取数据并得出适当的结论后,我想向客户端返回一条消息。 (我想我会对此感到满意)
所以我的两个问题是如何确定发送的两个字符串(客户端到服务器)在客户端是唯一的,如何在服务器端分离这两个字符串。 (我在考虑一系列字符串,但无法确定这是否可行或适当。)
我打算发布一些代码,但我不确定这会有什么帮助。
答案 0 :(得分:61)
我假设您使用TCP套接字进行客户端 - 服务器交互?将不同类型的数据发送到服务器并使其能够区分这两者的一种方法是将第一个字节(或更多,如果您有超过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
个字节。这使得readUTF
可以找到编码字符串的结尾。如果你决定自己的记录结构,那么你应该确保记录的结尾和类型是已知的或可检测的。
答案 1 :(得分:4)
最简单的方法是将套接字包装在ObjectInput / OutputStreams中并发送序列化的java对象。您可以创建包含相关数据的类,然后您不必担心处理二进制协议的细节问题。只需确保在编写每个对象“消息”后刷新对象流。
答案 2 :(得分:1)
//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);
}
}
}