嗨我为客户端和服务器写acode现在我想在clint one和clint 2之间传递消息,我没有成功在服务器端执行此操作我想为name和id构建数组并在我发送消息之后从客户端我可以选择服务器发送消息的位置或名称请求帮助我写这个 所以这就是克林特方面
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class client {
public static void main(String[] args) {
Socket socket = null;
try {
socket = new Socket("127.0.0.1", 7777);
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedReader readerFromCommandLine = new BufferedReader(new InputStreamReader(System.in));
PrintWriter writer = new PrintWriter(socket.getOutputStream());
while(true) {
System.out.println("Say something:");
String userInput = readerFromCommandLine.readLine();
writer.println(userInput);
writer.flush();
String input = reader.readLine();
System.out.println("Got from server: "+input);
if (userInput.equalsIgnoreCase("bye")) {
break;
}
}
}
catch(Exception e) {
System.err.println(e);
e.printStackTrace();
}
finally {
if (socket != null) {
try {
socket.close();
}
catch (Exception e) {
System.err.println(e);
e.printStackTrace();
}
}
}
}
}
所以现在我的代码看起来像这样吗? 因为我还没有能从一个客户发送给客户二
import java.awt.List;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class server {
public static void main(String[] args) {
ArrayList<Channel> my_clients = new ArrayList<Channel>();
ServerSocket ss = null;
try {
ss = new ServerSocket(7777);
while (true) {
//wait for a new client call - once got it, get the socket for
//that channel
System.out.println("Waiting for an incoming call");
Socket client = ss.accept();
Channel my_new_client = new Channel(client);
my_clients.add(my_new_client);
my_new_client.start();
//once the call has started read the client data
for(Channel my_client : my_clients) {
if(my_client.getName() == "Me") {
//my_client.writer("HELLO!");
}
}
//System.out.println("Accepted a new call");
//new Channel(client).start();
}
}
catch(Exception e) {
System.err.println(e);
e.printStackTrace();
}
finally {
if (ss != null) {
try {
ss.close();
}
catch(Exception e) {
System.err.println(e);
e.printStackTrace();
}
}
}
}
public static class Channel extends Thread {
private static int clientIndex = 0;
private int index;
private Socket socket = null;
public Channel(Socket socket) {
clientIndex++;
index = clientIndex;
this.socket = socket;
}
@Override
public void run() {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter writer = new PrintWriter(socket.getOutputStream());
while (true) {
String input = reader.readLine();
System.out.println("Got from client "+index+": "+input);
//bye bye
if (input.equalsIgnoreCase("bye")) {
break;
}
writer.println("Gotcha");
writer.flush();
}
}
catch(Exception e) {
System.err.println(e);
e.printStackTrace();
}
finally {
if (socket != null) {
try {
socket.close();
}
catch(Exception e) {
System.err.println(e);
e.printStackTrace();
}
}
}
}
}
}
答案 0 :(得分:0)
String userInput = readerFromCommandLine.readLine();
BufferedReader.readLine()是一个问题。在收到输入之前,它会阻塞你的线程。这意味着通信一次只能朝一个方向进行,如果两个客户都在等待,可能会完全被阻止。
DataFetcher可以解决这个问题;你可以用它来听一个单独的线程
答案 1 :(得分:0)
你到了一半。
您创建了一个Threaded Server,每个客户端的连接都会打开一个线程。然后该线程循环并等待消息。
当您将客户端与其自己的对象/属性及其流连接以写入和读取它们时,请考虑这些线程。
因此,每当您想要创建其线程的客户端连接时,将其添加到某种列表并启动其线程。例如:
在班级的顶端
List<Channel> my_clients = new List<Channel>();
在你的while循环中
Channel my_new_client = new Channel(client);
my_clients.add(my_new_client);
my_new_client.start();
然后当您想要向某个客户发送消息时。您可以循环所有线程并查找具有某种名称或唯一标识符的线程。例如:
for(Channel my_client : my_clients) {
if(my_client.getName() == "Me") {
my_client.write("HELLO!");
}
}
或者你可以向所有客户发送信息(广播):
for(Channel my_client : my_clients) {
my_client.write("HELLO!");
}
记得在断开连接时删除客户端!
// Can't remember the precise exception correct my if I'm wrong!
catch(SocketException ex) {
my_clients.remove(this);
}
请注意,您需要对某些人进行身份验证并了解客户端的名称,或者为他们提供一个UID,当您被指示向他们发送内容时,您会引用该UID。并且Channel类具有纵容的写入方法。
希望得到帮助!