我是Android的新手,对套接字编程有些新意。我有两个设备,运行Android 5.1
,直接与WiFi连接(不确定是否相关)。我有一个服务,服务器在套接字上侦听请求,然后将回复返回给客户端。
同样,客户端代码发送请求并侦听来自服务器的回复。服务器正在发送响应,但客户端永远不会收到消息,并且套接字超时。
服务器测试代码:
while (true) {
try {
Log.i(TAG, "test waiting for a request");
mServer = new ServerSocket(PORT);
Socket socket = mServer.accept(); //Block to receive message //
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Log.i(TAG, "Message received! " + in.readLine());
String msg = "This is my reply.";
OutputStream outputStream = socket.getOutputStream();
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
out.println(msg);
out.flush();
out.close();
} catch (SocketException e) {
Log.e(TAG, "Socket Accept Interrupted", e);
} catch (IOException e) {
Log.e(TAG, "Socket Failure", e);
} finally {
if (mServer != null && mServer.isBound()) {
try {
mServer.close();
} catch (IOException ioException) {
Log.e(TAG, "Failed to close socket trying to recover from SocketException", ioException);
}
}
}
}
客户端测试代码:
Socket socket = null;
SocketAddress addr = new InetSocketAddress(host, PORT);
int socketTOms = 5000;
try {
socket = new Socket(host, PORT);
socket.setKeepAlive(false);
String syncReq = "Request to server.";
//Send Request//
OutputStream outputStream = socket.getOutputStream();
outputStream.write(syncReq.getBytes());
socket.setSoTimeout(socketTOms);
//Rcv reply//
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Log.i(TAG, "Message received! " + in.readLine());
} catch (SocketTimeoutException e) {
Log.e(TAG, "Timeout while reading from socket: timeout=" + socketTOms);
} catch (Exception e) {
Log.e(TAG, "Exception", e);
} finally {
if (socket != null && socket.isConnected()) {
try {
socket.close();
} catch (IOException e) {
Log.e(TAG, "Exception while closing socket", e);
}
}
}
我通过Android Studio在两个不同的设备上运行服务器和客户端,并且可以在日志中看到服务器收到请求并发送回复,但客户端总是throws
{{1} }。我看到SocketTimeoutException
可以解决问题的其他地方,但它似乎没有任何影响。
看起来很简单,但我无法看到我在这里失踪的东西。
答案 0 :(得分:0)
可以在无限循环mServer = new ServerSocket(PORT);
之前尝试这行代码您是否尝试在服务器端应用中创建线程?这使得进程并行运行,以便在服务器等待请求时,应用程序不会挂起。首先尝试使用localhost的代码。要查找Inetaddress,只需使用InetAddress.getLocalHost()。然后运行它。对于与不同设备的通信,提供称为(NSD)(网络服务Discovary)的服务。
但是如果你想以这种方式运行,我已经为你编写了代码。
服务器端代码
TextView textView;
Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=(TextView)findViewById(R.id.textView);
button=(Button)findViewById(R.id.button);
button.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
connect();
}
}
);
}
public void connect()
{
MyServer myServer= new MyServer();
myServer.setEventListener(this);
myServer.startListening();
}
@Override
public void Display(String message) {
textView.setText("Client - "+ message);
}
}
客户端代码
TextView textView;
Button button;
Thread mThread;
Socket clientSocket;
Button sendBtn;
public String userText1;
ObjectOutputStream output;
EditText editText;
Object userText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=(TextView)findViewById(R.id.textView);
button=(Button)findViewById(R.id.button);
sendBtn=(Button)findViewById(R.id.sendBtn);
editText=(EditText)findViewById(R.id.editText);
sendBtn.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
userText=editText.getText().toString();
start();
}
}
);
public void start()
{
mThread= new Thread(new Runnable() {
@Override
public void run() {
try {
clientSocket = new Socket("127.0.0.1", 2001);
Log.v("binaya", "client socket created");
output = new ObjectOutputStream(clientSocket.getOutputStream());
output.writeObject(userText);
Message serverObj = Message.obtain();
ObjectInputStream input = new ObjectInputStream(clientSocket.getInputStream());
String strMsg = input.readObject().toString();
serverObj.obj = strMsg;
mHandler.sendMessage(serverObj);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
});
mThread.start();
}
Handler mHandler= new Handler()
{
@Override
public void handleMessage(Message msg) {
msgDisplay(msg.obj.toString());
}
};
private void msgDisplay(String msg) {
textView.setText("Server - " + msg);
}
我们使用过处理程序,因为在这种情况下我们无法从runnable内部触摸用户界面。 感谢
答案 1 :(得分:0)
想出来......
在客户端,我使用outputStream.write(...)
将请求发送到服务器,如下所示:
String syncReq = "Request to server.";
OutputStream outputStream = socket.getOutputStream();
outputStream.write(syncReq.getBytes());
但是使用BufferedReader.readLine()
在服务器上阅读:
Socket socket = mServer.accept(); //Block to receive message //
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Log.i(TAG, "Message received! " + in.readLine());
我的问题是outputStream.write(...)
在字符串的末尾没有附加'\ n',但服务器上的in.readLine()
需要它。因此服务器在等待'\ n'时阻塞;这反过来导致客户端套接字超时。