如何在套接字多线程中使用java中的TCP/IP将相同的数据从服务器发送到所有客户端?
我尝试从第一个客户端向服务器发送数组,第二个客户端向服务器发送数组。
当服务器接受两个客户端时,它将将两个数组合并为一个数组并对其进行排序,然后将其作为响应发送给两个客户端。
代码:
Server.java 文件:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class Server
{
public static void main(String[] zero) throws InterruptedException
{
ServerSocket socket;
int nb = 0;
try {
socket = new ServerSocket(6789,2);
//creé le thread
Thread t = new Thread(new Accepter_clients(socket,nb));
t.start();
System.out.println("Mes employeurs sont prêts !");
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
//**********************************************************************************
//**********************************************************************************
class Accepter_clients implements Runnable
{
private ServerSocket socketserver;
private Socket socket;
private int nbrclient ;
// private Boolean etat=Boolean.FALSE;
ObjectOutputStream out;
ObjectInputStream in ;
int [] tableauAEmettre ;
List<Object> liste = new ArrayList<Object>();
public Accepter_clients(ServerSocket s,int nb)
{
this.socketserver = s;
this.nbrclient=nb;
System.out.println("serveur n :"+nbrclient);
}
public void run() //pour un seul thread à la fois
{
try {
while(true)
{
this.socket = socketserver.accept(); // Un client se connecte onl'accepte
System.out.println("Le client numéro "+nbrclient+" est connecté !");
nbrclient++;
this.out = new ObjectOutputStream(this.socket.getOutputStream());
//System.out.println("serveur envoi: " + tabl);
read();
write();
this.socket.close();
}
}
catch (IOException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.getMessage();
}
}
public synchronized void read() throws ClassNotFoundException, IOException
{
this.in = new ObjectInputStream(socket.getInputStream());
Object objetRecu= this.in.readObject();
tableauAEmettre= (int[]) objetRecu;
for( int i=0;i<tableauAEmettre.length;i++){
liste.add(tableauAEmettre[i]);
}
System.out.println("serveur recoit depuis Client: "+ (nbrclient-1) +" : "+ liste);
this.notify();
}
public synchronized void write()
{
try {
System.out.println("Je suis la !!!");
this.wait();
Object tt = liste.toArray();
int[] t = (int[]) tt ;
Arrays.sort(t);
// List<Object> tabl=tri(liste);
System.out.println("Je suis la hihihih !!!");
this.out.writeObject(t);
this.out.flush();
this.notify();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.getMessage();
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.getMessage();
}
}
//Fonction permet de trie les tableau
}
Client.java 文件:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.*;
import java.util.Arrays;
public class Client {
public static void main(String[] zero) throws ClassNotFoundException{
Socket socket;
ObjectInputStream in;
ObjectOutputStream out ;
try {
socket = new Socket("localhost",6789);
out = new ObjectOutputStream(socket.getOutputStream());
out.flush();
int lower = 3;
int higher = 15;
int random = (int)(Math.random() * (higher-lower)) + lower;
int[] tableauAEmettre= new int[random];
for (int i=0;i<random;i++)
{
tableauAEmettre[i]=(int)(Math.random() * (40-0)) + 0;
}
out.writeObject(tableauAEmettre);
out.flush();
System.out.println("Client 1 envoi: " + Arrays.toString(tableauAEmettre));
in = new ObjectInputStream(socket.getInputStream());
Object objetRecu = in.readObject();
int[] tableauRecu = (int[]) objetRecu;
System.out.println("Client 1 recoit: " + Arrays.toString(tableauRecu));
in.close();
out.close();
socket.close();
socket.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
Client2.java 文件:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.*;
import java.util.Arrays;
public class Client2 {
public static void main(String[] zero) throws ClassNotFoundException{
Socket socket;
ObjectInputStream in;
ObjectOutputStream out ;
try {
socket = new Socket("localhost",6789);
out = new ObjectOutputStream(socket.getOutputStream());
out.flush();
int lower = 3;
int higher = 15;
int random = (int)(Math.random() * (higher-lower)) + lower;
int[] tableauAEmettre= new int[random];
for (int i=0;i<random;i++)
{
tableauAEmettre[i]=(int)(Math.random() * (40-0)) + 0;
}
out.writeObject(tableauAEmettre);
out.flush();
System.out.println("Client 2 envoi: " + Arrays.toString(tableauAEmettre));
in = new ObjectInputStream(socket.getInputStream());
Object objetRecu = in.readObject();
int[] tableauRecu = (int[]) objetRecu;
System.out.println("Client 2 recoit: " + Arrays.toString(tableauRecu));
in.close();
out.close();
socket.close();
socket.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
您将希望接受连接线程与读取和写入分开,正如 Peter Lowry 所建议的那样。我的示例非常精简,需要更多代码才能正常工作,但应该足以说明。
有助于有一些类来帮助管理套接字
Class Connection {//possibly implements runnable
Socket socket;
ObjectInputStream in;
ObjectOutputStream out;
public Connection(Socket s) {
this.socket = s;
this.in = s.getInputStream();
this.out = s.getOutputStream();
}
public void sendData(Object o)
{
out.sendObject(o);
}
}
并在主函数中..设置接受线程并具有用于读取和写入的服务器循环。
main(String[] zero) throws ClassNotFoundException{
ArrayList<Connection> connections = new ArrayList<Connection>();
//...
Thread t = new Thread(new Accepter_clients(connections));
t.start();
//Server read/write loop
boolean continue = true;
while (continue)
{
synchronized(connections)
{
for (Connection c : connections)
{
//c.sendData();
}
for (Connection c : connections)
{
//c.readData();
}
}
}
}
最后,您的接受器线程...监视新连接并将其添加到连接列表中。
ArrayList<Connection> connections;
public Accepter_clients(ArrayList<Connection> connections)
{
this.connections = connections;
}
public void run()
{
ServerSocket s; //initialize here
while (true) //some boolean to continue instead
{
//...
Connection newConn = new Connection(s.accept);
synchronized (connections) { //cant modify list while using it elsewhere
connections.add(newConn);
}
}
}
我是一名优秀的程序员,十分优秀!