【发布时间】:2016-07-24 23:32:01
【问题描述】:
我正在尝试开发一个应用程序,其中
1.客户端向服务器发送连接请求(IP地址+端口号)+使用“PrintStream”发送数据+尝试从服务器读取数据(使用Inputstream)
2.Client创建socket。
3.Server读取Client发送的数据
4.SERVER 在 3 号同一时间点使用“PrintStream”写入数据。
问题出在第 4 点 SERVER 写入的数据未被客户端的“INPUTSTREAM”读取(第 1 点) 我不知道这些同时操作是否可能。如果可能,那么如何。如果不是,那么替代方式是什么?
服务器代码
package com.example.loneranger.ser;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Enumeration;
public class MainActivity extends Activity {
TextView ip;
TextView msg;
String data = "";
ServerSocket httpServerSocket;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ip = (TextView) findViewById(R.id.infoip);
msg = (TextView) findViewById(R.id.msg);
ip.setText(getIpAddress() + ":"
+ 8080 + "\n");
Server server = new Server();
server.start();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (httpServerSocket != null) {
try {
httpServerSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private String getIpAddress() {
String ip = "";
try {
Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface
.getNetworkInterfaces();
while (enumNetworkInterfaces.hasMoreElements()) {
NetworkInterface networkInterface = enumNetworkInterfaces
.nextElement();
Enumeration<InetAddress> enumInetAddress = networkInterface
.getInetAddresses();
while (enumInetAddress.hasMoreElements()) {
InetAddress inetAddress = enumInetAddress.nextElement();
if (inetAddress.isSiteLocalAddress()) {
ip += "IP: "
+ inetAddress.getHostAddress() + "\n";
}
}
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ip += "Something Wrong! " + e.toString() + "\n";
}
return ip;
}
private class Server extends Thread {
@Override
public void run() {
Socket socket = null;
try {
httpServerSocket = new ServerSocket(8888);
while(true){
socket = httpServerSocket.accept();
HttpResponseThread httpResponseThread =
new HttpResponseThread(
socket);
httpResponseThread.start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private class HttpResponseThread extends Thread {
Socket socket;
HttpResponseThread(Socket socket){
this.socket = socket;
}
@Override
public void run() {
BufferedReader BReader;
PrintWriter printer;
String request;
try { InputStream inputStream = socket.getInputStream();
BReader = new BufferedReader(new InputStreamReader(inputStream));
request = BReader.readLine();
Thread.sleep(500);
printer = new PrintWriter(socket.getOutputStream(), true);
printer.print("hello laundu");
printer.flush();
String ip123=socket.getInetAddress().toString();
printer.close();
BReader.close();
socket.close();
data += "Request of " + request
+ " from "+ ip123 + "\n";
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
msg.setText(data);
}
});
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return;
}
}
}
客户代码
mport android.os.AsyncTask;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String response = "";
TextView textResponse;
MainActivity activity;
OutputStream outputStream;
BufferedReader BReader;
String request;
Client(String addr, int port, TextView textResponse) {
dstAddress = addr;
dstPort = port;
this.textResponse=textResponse;
this.activity=activity;
}
@Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
try {
socket = new Socket(dstAddress, dstPort);
Server server = new Server(socket);
server.start();
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
out.print("futfujb");
out.flush();
/*
* notice: inputStream.read() will block if no data return
*/
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "UnknownHostException: " + e.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "IOException: " + e.toString();
} /*finally {
if (socket != null) {
try {
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}*/
return null;
}
@Override
protected void onPostExecute(Void result) {
textResponse.setText(response);
super.onPostExecute(result);
}
private class Server extends Thread {
Socket socket;
Server(Socket socket)
{
this.socket=socket;
}
@Override
public void run() {
try { //Thread.sleep(500);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(
1024);
byte[] buffer = new byte[1024];
int bytesRead;
InputStream inputStream = socket.getInputStream();
if(inputStream.available()>0)
{
while ((bytesRead = inputStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, bytesRead);
response += byteArrayOutputStream.toString("UTF-8");
}
}
inputStream.close();
socket.close();
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
【问题讨论】:
-
服务器为什么要新建一个socket连接?出现此问题的代码在哪里?
-
这里没有对应于'(2)服务器获取请求(3)服务器创建新连接'的内容。有一个新的谜团:为什么你的客户端中有一个名为
Server的类?您的问题的解决方案是删除available()测试。 -
删除availaible()后输入流卡住了。
-
服务器正在读取客户端从未发送的行。客户端需要发送请求。当服务器关闭套接字时,它将退出读取循环。
标签: android sockets serversocket