多线程服务器只从一个JAVA客户端接收数据
我创建了一个简单的多线程服务器。每次它接受客户端时,都会创建DataInputStream和DataOutputStream,并启动通信 服务器:多线程服务器只从一个JAVA客户端接收数据,java,android,multithreading,server,datainputstream,Java,Android,Multithreading,Server,Datainputstream,我创建了一个简单的多线程服务器。每次它接受客户端时,都会创建DataInputStream和DataOutputStream,并启动通信 服务器: public class Connection implements Runnable{ boolean isAlreadyOpened = false; @Override public void run() { // TODO Auto-generated method stub try {
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();
}
}
但结果是一样的
编辑:
android客户端代码
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应用程序客户端代码
@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();
}
}
公共类连接实现可运行{
List sList=new ArrayList();
插座;
int i=0;
@凌驾
公开募捐{
//TODO自动生成的方法存根
试一试{
ServerSocket ss=新的ServerSocket(7000);
while(true){
System.out.println(“服务器侦听”);
s=ss.accept();
列表。添加(s);
System.out.println(“接受的客户端--”+s.toString());
线程t2=新线程(新可运行(){
公开募捐{
试一试{
DataInputStream dis=新的DataInputStream(s.getInputStream());
while(true)
{
字符串测试=dis.readUTF();
System.out.println(“从--”发送的消息+sList.get(i.toString());
系统输出打印LN(测试);
而(i
按照EJP的建议,通过这种方式解决了我的问题…无法重现
测试程序,从编辑的代码中复制粘贴,并在我使用Java 7时将final
添加到sockets
,并添加客户端代码:
public class Connection implements Runnable
{
@Override
public void run()
{
try
{
ServerSocket ss = new ServerSocket(7000);
while (true)
{
System.out.println("Server is listening");
final 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)
{
e.printStackTrace();
}
finally
{
try
{
s.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
});
t2.start();
}
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException
{
Connection c = new Connection();
Thread t1 = new Thread(c);
t1.setDaemon(true);
t1.start();
Runnable r = new Runnable()
{
public void run()
{
try (Socket s = new Socket("localhost", 7000))
{
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
DataInputStream dis = new DataInputStream(s.getInputStream());
for (int i = 0; i < 10; i++)
{
dos.writeUTF("Hello from "+Thread.currentThread().getName());
String reply = dis.readUTF();
Thread.sleep(10*1000);
}
}
catch (IOException|InterruptedException exc)
{
exc.printStackTrace();
}
}
};
Thread t2 = new Thread(r);
Thread t3 = new Thread(r);
t2.start();
t3.start();
t2.join();
t3.join();
}
}
您永远不会关闭已接受的套接字。否则此代码应该可以工作。您确定问题不在客户端吗?但是当
s
不是最终版本时,此代码如何编译?@peter.petrov此代码将在readUTF()中阻塞
直到收到数据或发生异常。这里没有问题。在循环之后必须关闭接受的套接字s
。isAlreadyOpened
变量是没有意义的:删除它。当然。我不是说要把它放在哪里,但实际上它应该在catch
之后的块中关闭。它实际上,应该在catch
之后在finally
块中关闭。我并不是说它可以解决您的问题。没有理由在线程外声明套接字。我的代码是一样的。但它不起作用。这是java8的问题吗?还是与我的客户端之间的差异有关(一个JavaApp和一个Android)?发布你的客户端,我会告诉你。我看不出这些客户端不起作用的任何原因。客户端不应该“接收另一个客户端发送的消息”。不清楚你在问什么。服务器必须将其发送给另一个客户端。因此,它需要一个客户端套接字列表,并在收到消息时遍历所有这些套接字。我强烈反对建议使用列表
而不是数组。请确保在接受的套接字关闭时将其清理干净。
Server is listening
Client Accepted
Server is listening
Client Accepted
Server is listening
Hello from Thread-1
Hello from Thread-2
Hello from Thread-2
Hello from Thread-1
Hello from Thread-2
Hello from Thread-1
Hello from Thread-2
Hello from Thread-1
Hello from Thread-1
Hello from Thread-2
Hello from Thread-1
Hello from Thread-2
Hello from Thread-2
Hello from Thread-1
Hello from Thread-1
Hello from Thread-2
Hello from Thread-2
Hello from Thread-1
Hello from Thread-2
Hello from Thread-1