【发布时间】:2016-05-22 21:57:28
【问题描述】:
我创建了一个简单的多线程服务器。每次它接受客户端时,都会创建一个 DataInputStream 和 DataOutputStream 并开始通信
服务器:
public class Connection implements Runnable{
boolean isAlreadyOpened = false;
@Override
public void run() {
// TODO Auto-generated method stub
try {
ServerSocket ss = new ServerSocket(7000);
while(true){
System.out.println("Il Server sta cercando Connessioni");
Socket s = ss.accept();
System.out.println("Il Server ha accettato un Client");
Thread t2 = new Thread(new Runnable(){
public void run(){
try {
DataInputStream dis = new DataInputStream(s.getInputStream());
isAlreadyOpened = true;
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
while(true){
String test = dis.readUTF();
dos.writeUTF(test);
System.out.println(test);
dos.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
isAlreadyOpened = false;
}
}
});
t2.start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
我尝试连接一个 Android 应用程序和一个 JavaApp;这两个程序每 40 秒通过 writeUTF 发送一个字符串。两个客户端都正确建立了连接,但服务器仅从最后一个连接到服务器的客户端接收数据。 如何允许服务器从/向所有客户端接收/发送数据?
编辑:
我已经尝试过设置:
public class Connection implements Runnable {
@Override
public void run() {
try {
ServerSocket ss = new ServerSocket(7000);
while (true) {
System.out.println("Server is listening");
Socket s = ss.accept();
System.out.println("Client Accepted");
Thread t2 = new Thread(new Runnable() {
public void run() {
try {
DataInputStream dis = new DataInputStream(s.getInputStream());
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
while (true) {
String test = dis.readUTF();
dos.writeUTF(test);
System.out.println(test);
dos.flush();
}
} catch (IOException
e.printStackTrace();
} finally {
try {
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
t2.start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
但结果是一样的
编辑:
Andorid 客户端代码
public class Connection implements Runnable {
@Override
public void run() {
try {
Socket s = new Socket("127.0.0.1", 7000);
DataInputStream dis = new DataInputStream(s.getInputStream());
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
while(true){
dos.writeUTF("FromAndroid");
Log.d("InputStreammmm", dis.readUTF());
Thread.sleep(10000)
}
} catch (IOException e) {
e.printStackTrace();
}
}
JAVA APP客户端代码
@Override
public void run() {
try {
Socket socket = new Socket("127.0.0.1", 7000);
System.out.println("Connessooo");
DataInputStream dis = new DataInputStream(socket.getInputStream());
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
while(true){
dos.writeUTF("Invioooooooooooooooooooooooooo");
result = dis.readUTF();
System.out.println(result);
Thread.sleep(10000);
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
使用套接字列表编辑:
public class Connection implements Runnable {
List<Socket> sList = new ArrayList<>();
Socket s;
int i = 0;
@Override
public void run() {
// TODO Auto-generated method stub
try {
ServerSocket ss = new ServerSocket(7000);
while (true) {
System.out.println("Server Listening");
s = ss.accept();
sList.add(s);
System.out.println("Accepted Client --- " +s.toString());
Thread t2 = new Thread(new Runnable() {
public void run() {
try {
DataInputStream dis = new DataInputStream(s.getInputStream());
while (true)
{
String test = dis.readUTF();
System.out.println("Message sent from -- " + sList.get(i).toString());
System.out.println(test);
while(i < sList.size()){
DataOutputStream dos = new DataOutputStream(sList.get(i).getOutputStream());
dos.writeUTF(test);
System.out.println("Message Sent to -- " + sList.get(i).toString());
dos.flush();
++i;
}
i=0;
}
} catch (IOException e)
{
e.printStackTrace();
} finally
{
try
{
System.out.println("Closing Socket --- " + sList.get(i).toString());
sList.get(i).close();
sList.remove(i);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
});
t2.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
按照 EJP 的建议,以这种方式解决了我的问题...
【问题讨论】:
-
你永远不会关闭接受的套接字。但否则这段代码应该可以工作。你确定问题不在客户端?但是当
s不是final 时,这段代码如何编译? -
@peter.petrov 代码将阻塞在
readUTF(),直到收到数据或发生异常。这里没有错。 -
您必须在循环后关闭接受的套接字
s。isAlreadyOpened变量毫无意义:删除它。 -
当然。这不是我说要放的地方,但实际上它应该在
catch之后的finally块中关闭。 -
它实际上应该在
catch之后的finally块中关闭。并不是说我声称它会解决你的问题。没有理由在线程外声明套接字。
标签: java android multithreading server datainputstream