基本上我想要做的是开发一个聊天程序(即时通讯工具和IRC之间的东西)来提高我的java技能。
但到目前为止我遇到了一个大问题:如果有多个客户端,我不知道如何正确设置流。客户端和服务器之间的1:1聊天工作很容易,但我只是不知道什么是todo,所以超过1个客户端可以在同一个聊天中使用服务器。
这就是我所得到的,但我怀疑它会非常有用,因为它只是来自服务器的1个永久流。
private void connect() throws IOException {
showMessage("Trying to connect \n");
connection = new Socket(InetAddress.getByName(serverIP),27499);
showMessage("connected to "+connection.getInetAddress().getHostName());
}
private void streams() throws IOException{
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());
showMessage("\n streams working");
}
答案 0 :(得分:0)
要从一个程序中的多个流中读取,您将不得不使用多线程。因为从流中读取是同步的,所以您需要从每个线程的一个流中读取。有关多线程的详细信息,请参阅java tutorial on threads。
答案 1 :(得分:0)
ServerSocket
和Thread
。当客户端连接时,您将该端口的输入和输出流注册到固定池并阻塞,直到发送输入。然后将输入复制到每个其他客户端并发送。这是从命令行运行的基本程序:
服务器代码:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class ChatServer {
static int PORT_NUMBER = 2012;
public static void main(String[] args) throws IOException {
while (true) {
try (ServerSocket ss = new ServerSocket(PORT_NUMBER)) {
System.out.println("Server waiting @" + ss.getInetAddress());
Socket s = ss.accept();
System.out.println("connection from:" + s.getInetAddress());
new Worker(s).start();
}
}
}
static class Worker extends Thread {
final static ArrayList<PrintStream> os = new ArrayList(10);
Socket clientSocket;
BufferedReader fromClient;
public Worker(Socket clientSocket) throws IOException {
this.clientSocket = clientSocket;
PrintStream toClient=new PrintStream(new BufferedOutputStream(this.clientSocket.getOutputStream()));
toClient.println("connected to server");
os.add(toClient);
fromClient = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
}
@Override
public void run() {
while (true) {
try {
String message = fromClient.readLine();
synchronized (os) {
for (PrintStream toClient : os) {
toClient.println(message);
toClient.flush();
}
}
} catch (IOException ex) {
//user discnnected
try {
clientSocket.close();
} catch (IOException ex1) {
}
}
}
}
}
}
客户代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
public class Client {
public static void main(String[] args) throws IOException {
final BufferedReader fromUser = new BufferedReader(new InputStreamReader(System.in));
PrintStream toUser = System.out;
BufferedReader fromServer;
final PrintStream toServer;
Socket s = null;
System.out.println("Server IP Address?");
String host;
String port = "";
host = fromUser.readLine();
System.out.println("Server Port Number?");
port = fromUser.readLine();
s = new Socket(host, Integer.valueOf(port));
int read;
char[] buffer = new char[1024];
fromServer = new BufferedReader(new InputStreamReader(s.getInputStream()));
toServer = new PrintStream(s.getOutputStream());
new Thread() {
@Override
public void run() {
while (true) {
try {
toServer.println(">>>" + fromUser.readLine());
toServer.flush();
} catch (IOException ex) {
System.err.println(ex);
}
}
}
}.start();
while (true) {
while ((read = fromServer.read(buffer)) != -1) {
toUser.print(String.valueOf(buffer, 0, read));
}
toUser.flush();
}
}
}
答案 2 :(得分:0)
我已使用ServerSocket(int port)
和Socket ServerSocket.accept()
多次完成此操作。通过让它监听您希望聊天服务器客户端监听的一个端口,这可以非常简单。主线程将阻止等待下一个客户端连接,然后将Socket对象返回到该特定客户端。通常,您会希望将它们放在一个列表中,以便一般地处理n个客户端。
而且,是的,您可能希望确保每个Socket
位于不同的主题中,但这完全取决于您作为程序员。
请记住,由于客户端使用不同的源端口,独特的5元组(SrcIP,SrcPort,DstIP,DstPort,TCP / UDP /其他),因此无需重定向到服务器上的其他端口IP协议)将允许重用一个服务器端口。因此,为什么我们都使用stackoverflow.com端口80。
快乐编码。