首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在客户端服务器消息传递程序中创建多个对等聊天

如何在客户端服务器消息传递程序中创建多个对等聊天
EN

Stack Overflow用户
提问于 2014-03-19 16:36:19
回答 2查看 8.1K关注 0票数 0

我正在尝试创建一个信使程序,并且已经成功地使用套接字建立了客户机-服务器连接。然而,我发现很难对多个客户同时通信的过程进行编码。下面的代码显示了用于ClientThread类中的聊天的方法,该类使用存储在共享ArrayList中的线程来调节客户端和服务器之间的交互。您将如何在这里实现多个对等聊天的代码?

startChat方法:

代码语言:javascript
复制
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方法:

代码语言:javascript
复制
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方法:

代码语言:javascript
复制
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类:

代码语言:javascript
复制
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和其他代码那么先进,但是我试图从头开始构建它,并被困在这里长达几千年之久。在互联网上进行拖网捕鱼没有任何帮助:

任何建议和批评都是上帝派来的!

提前谢谢各位。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-20 17:39:17

好的。您可以这样做: Im专注于控制台应用程序

  • 定义类调用消息:

代码语言:javascript
复制
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;
}
  • 定义一个全局变量: ArrayList消息;保存所有不可执行的消息。
  • 因此,当您开始与客户端聊天时->创建新线程来读取来自him.When的消息时,您将收到一条消息。您必须将该消息放到数组列表中:消息(您必须记住同步它)。因为它将被许多线程调用)

同步(消息){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:这是一个想法:)祝你好运

票数 0
EN

Stack Overflow用户

发布于 2014-03-19 16:51:45

我可以给你一个解决方案,但你必须实现它。

我们有:

  • 服务器A、客户端B& C. B&C已通过TCP连接连接到服务器
  • 第一,客户机B想与C聊天,所以B必须通过UDP向服务器发送消息。
  • 第二,服务器将从B ==>服务器接收UDP消息,知道B通过UDP连接到服务器的哪个ip和B端口。然后服务器向C发送一条消息(TCP),其中包含关于UDP ip:端口B的信息。
  • 客户端C将通过TCP接收来自服务器的消息。所以C知道ip:端口B正在监听。->如果C接受与B聊天。C必须向服务器发送UDP消息,告诉服务器C接受与B进行对话。
  • 第四:服务器将通过UDP接收该消息。所以服务器还知道ip: UDP中的C端口。
  • 5:服务器将通过TCP将UDP ip:C端口传输到B(如果需要,也可以使用UDP )。
  • 客户端B会收到它&知道udp ip: C端口,这样他们就可以通过UDP协议开始聊天了。

它被称为UDP/TCP孔冲压。您可以对其进行更多的研究以实现。

P/S:但是这个方法不适用于Symetric

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22512424

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档