我正在尝试创建一个信使程序,并且已经成功地使用套接字建立了客户机-服务器连接。然而,我发现很难对多个客户同时通信的过程进行编码。下面的代码显示了用于ClientThread类中的聊天的方法,该类使用存储在共享ArrayList中的线程来调节客户端和服务器之间的交互。您将如何在这里实现多个对等聊天的代码?
startChat方法:
public void startChat()
{
// start the convo!
// first of all the user chooses who to speak to
// starts a loop until user enters a valid username or 'Group'
String line = "";
boolean validCommand = false;
while(validCommand == false)
{
try {
line = in.readLine();
} catch (IOException e) {
System.out.println("Problem reading reply about user chat");
}
if(line.equalsIgnoreCase("Group"))
{
validCommand = true;
chatAll(); // an integer of negative one starts a chat with everyone
}
else
{
synchronized(this){
// find user
for(int i = 0; i < threads.size(); i++)
{
if(threads.get(i) != null && threads.get(i).username != null)
{
if(threads.get(i).username.equals(line)) // means that we have found the index of the thread that the client wants to speak to
{
/*// START : BETWEEN THESE CAPITALISED COMMENTS IS MY ATTEMPT TO INITIATE TWO WAY CHAT
int thisIndex = -1;
for(int j = 0; j < threads.size(); j++) // gets the index of this thread object in the array
{
if(threads.get(j) == this)
{
thisIndex = j;
// out.println(j);
}
}
if(thisIndex != -1)
{
threads.get(i).out.println(username + " is trying to connect");
threads.get(i).processChat(thisIndex); // this is the line causing the problem!
}
// END : BETWEEN THESE CAPITALISED COMMENTS IS MY ATTEMPT TO INITIATE TWO WAY CHAT */
threads.get(i).out.println(username + " is trying to connect");
out.println("Chat with " + threads.get(i).username);
processChat(i);
validCommand = true;
}
// if the command is not group and not a username, it is not valid and we ask the user to re-enter
else if(i == threads.size() - 1)
{
out.println("This command is not valid, please re-enter");
}
}
}
} // end of synchronised bit
} // end of else statement
} // end of while loop
} allChat方法:
void chatAll()
//for the purpose of group chat
{
out.println("Group chat initiated");
boolean d = true;
while(d == true)
{
String message = "";
try {
message = in.readLine();
} catch (IOException e) {
System.out.println("Can't read line from client");
}
if(message.contains("goodbye") == true)
{
d = false;
}
else
{
synchronized(this)
{
for(int j = 0; j < threads.size(); j++)
{
if(threads.get(j) != null)
{
threads.get(j).out.println(username + ": " + message);
}
}
}
}
}
}processChat方法:
void processChat(int i)
//for the purpose of talking to pre-defined user
{
boolean d = true;
while(d == true)
{
String message = "";
try {
message = in.readLine();
} catch (IOException e) {
System.out.println("Can't read message from client");
}
if(message.contains("goodbye") == true)
{
d = false;
}
else {
if(threads.get(i) != null)
{
threads.get(i).out.println(username + ": " + message);
}
}
}
}为了更好地度量和引用,这里是整个客户端类(混淆地标记为ThreadedClient,而不是ClientThread haha)。
ThreadedClient类:
import java.net.*;
import java.io.*;
public class ThreadedClient implements Runnable {
// client socket
private static Socket clientSocket = null;
//I/O streams to and from the server
private static BufferedReader in = null;
private static PrintStream out = null;
// Input stream to read user input
private static BufferedReader inputReader = null;
private boolean open = true;
public ThreadedClient(String host, int port)
{
startConnection(host, port);
}
public void startConnection(String host, int port)
{
//open up the socket
try {
clientSocket = new Socket(host, port);
} catch (UnknownHostException e) {
System.out.println("The host name '" + host + "' isn't known");
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("Cannot create socket");
}
// connect I/O streams
try {
in = new BufferedReader(new InputStreamReader(new DataInputStream(clientSocket.getInputStream())));
out = new PrintStream(clientSocket.getOutputStream());
inputReader = new BufferedReader(new InputStreamReader(System.in));
} catch (IOException e) {
System.out.println("Problem connecting streams");
}
// process the chat itself
// the thread deals with input coming in
Thread thread = new Thread(this);
thread.start();
// the loop deals with output
while(open == true)
{
String message;
try {
message = inputReader.readLine();
out.println(message);
if(message.contains("goodbye") == true)
{
open = false;
}
} catch (IOException e) {
System.out.println("Problem sending messages");
}
}
// chat is done, so we can close resources
try {
in.close();
inputReader.close();
out.close();
clientSocket.close();
} catch (IOException e) {
System.out.println("Problem closing resources");
}
}
// run method for sending input out. I imagine this will not be necessary in the GUI implemented version, as we can use
// an action listener for the send function, e.g. one that reads a text field into a output stream everytime the user clicks enter
public void run() {
while(open == true)
{
try {
String response = in.readLine();
if(response.contains("goodbye") == true)
{
open = false;
}
System.out.println(response);
} catch (IOException e) {
System.out.println("Problem recieving messages");
}
}
}
public static void main(String[] args)
{
ThreadedClient socket = new ThreadedClient("localhost", 50000);
}}
我知道,这段代码可能没有我在这个论坛上看到的其他代码以及DreamInCode和其他代码那么先进,但是我试图从头开始构建它,并被困在这里长达几千年之久。在互联网上进行拖网捕鱼没有任何帮助:
任何建议和批评都是上帝派来的!
提前谢谢各位。
发布于 2014-03-20 17:39:17
好的。您可以这样做: Im专注于控制台应用程序
class Message
{
public String username; // the sender that send this message to u.So you can reply back to this user
public boolean groupMessage; // this message is group message or not
public String message;
}同步(消息){messages.add(.);//这里的新消息}
同时(正在运行){
同步(消息){ if(messages.size()<=0) messages.wait();//当您收到一条新消息时,您必须通知}同步消息(Messages){ message msg = messages.get(0);messages.remove(0);showmessage_to_ouput(msg);//类似的内容。字符串s=从输入//读取以响应此消息。回复(.)//您可以在这里检查此消息是否是组消息- ..etc }
}
P/S:这是一个想法:)祝你好运
发布于 2014-03-19 16:51:45
我可以给你一个解决方案,但你必须实现它。
我们有:
它被称为UDP/TCP孔冲压。您可以对其进行更多的研究以实现。
P/S:但是这个方法不适用于Symetric
https://stackoverflow.com/questions/22512424
复制相似问题