当前位置: 首页 > 知识库问答 >
问题:

JavaSoket线程服务器将消息发送回特定客户端

归翔
2023-03-14

我正在开发一个客户端-服务器JavaGUI(Swing)应用程序,我已经成功地创建了线程服务器类,从客户端接收消息,并向服务器发送消息的客户端类,客户端和服务器都是GUI应用程序,我正在为我的互联网caffe开发一个局域网订购系统。.我是新的套接字编程,我现在需要的是一种方法,当服务器GUI应用程序的用户通过单击JLabel查看GUI中的顺序时,从服务器发送消息到客户端。

那么,如何从服务器向发送触发特定JLabel的消息的特定客户端发送消息呢?以及如何向包含该消息的客户端用户显示JOptionpane(客户端有几个JPanel类)

发送消息的客户端类:

package questorderingsystem.engine;

import java.io.BufferedWriter; 
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
    public class SendItemAndIp {

    private static Socket socket;
    public static String message = "";
    public static void sendToServer(String item) throws UnknownHostException, IOException{
    InetAddress IP= InetAddress.getLocalHost();
    String ipadr = IP.toString();
    String PCNUM = ipadr.substring(ipadr.length() - 2);

    //IP SERVERAA 
    String host = "192.168.55.151";
    int port = 1978;
        InetAddress address = InetAddress.getByName(host);
        socket = new Socket(address, port);
        //Send the message to the server
        OutputStream os = socket.getOutputStream();
        OutputStreamWriter osw = new OutputStreamWriter(os);
        BufferedWriter bw = new BufferedWriter(osw);
        String oneLine = item.replace("\n", "%");
        String sendMessage = oneLine +"/"+ PCNUM;
        bw.write(sendMessage);
        bw.flush();
        socket.close();
}
}

线程服务器

package questorderingsystemserver;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class ThreadedEchoServer {

static final int PORT = 1978;

public static void startServer() {
    ServerSocket serverSocket = null;
    Socket socket = null;

    try {
        serverSocket = new ServerSocket(PORT);
    } catch (IOException e) {
        e.printStackTrace();

    }
    while (true) {
        try {
            socket = serverSocket.accept();
        } catch (IOException e) {
            System.out.println("I/O error: " + e);
        }
        // new thread for a client
        new EchoThread(socket).start();
    }
}
}

EchoServer

package questorderingsystemserver;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JLabel;

public class EchoThread extends Thread {
protected Socket socket;



}
public EchoThread(Socket clientSocket) {
    this.socket = clientSocket;
}
public void run() {
    InputStream inp = null;
    BufferedReader brinp = null;
    DataOutputStream out = null;
    try {
        inp = socket.getInputStream();
        brinp = new BufferedReader(new InputStreamReader(inp));
        out = new DataOutputStream(socket.getOutputStream());
    } catch (IOException e) {
        return;
    }
    String line;
    while (true) {
        try {
            line = brinp.readLine();
            if ((line == null) || line.equalsIgnoreCase("QUIT")) {
                socket.close();
                return;
            } else {
                //do something

                out.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
            return;
        } catch (UnsupportedAudioFileException ex) {
            Logger.getLogger(EchoThread.class.getName()).log(Level.SEVERE, null, ex);
        } catch (LineUnavailableException ex) {
            Logger.getLogger(EchoThread.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
}

共有2个答案

陈坚
2023-03-14

您几乎完成了,因为您将第一个命令指定为“QUIT”,所以您可以根据需要实现更多命令。

好的部分是使用BufferedReader和DataOutputStream处理输入和输出。

请注意,如果您喜欢使用字符串在客户端和服务器之间进行通信,那么您可以选择打印流(PrintStream)或打印编写器(PrintWriter),而不是数据输出流(DataOutputStream)。

线程服务器文件/类中,将这一行放入新的EchoThread(套接字)。开始() 在您接受侧边的套接字后重试(现在安全了)。

在客户端类/文件中,当您为服务器发送一些命令时,您可能也会期待一些结果。因此,就像您创建的回显类一样,您可以为客户端做同样的事情并处理响应。

马阳曦
2023-03-14

套接字建立端到端连接,因此每个套接字都连接到另一个特定的套接字。服务器套接字稍有不同。查看ServerSocket::accept的返回。返回的对象是套接字。不仅有一个套接字,还有一个直接连接到发出请求的客户端的套接字。由于您为每个服务器套接字创建了一个新的EchoThread,因此每个EchoThread都连接到自己的客户端。

您已经在从套接字读取数据,以检查连接是否已关闭或是否已发出“退出命令”。现在,您只需在您的else子句中使用前面创建的DataOutputStream来响应:

while (true) {
    try {
        line = brinp.readLine();
        if ((line == null) || line.equalsIgnoreCase("QUIT")) {
            socket.close();
            return;
        } else {
            //writing here:
            out.write("Some response text\n".getBytes());
            out.flush();
        }
    } catch (IOException e) {
      ...
    } ...
}

但请注意,repsonse字符串需要以字符结尾,这取决于客户端的“读取逻辑”。

 类似资料:
  • 问题内容: 向所有客户端发送消息效果很好,但是我想向特定的用户名发送消息。我的server.js文件看起来像。它的作用是在运行时,客户端代码将用户添加到对象用户名以及套接字对象中。并立即将单个消息返回给每个连接的客户端。 发出消息的部分 问题答案: 试试这个: socket.id由socket.io保存,并且包含客户端的唯一ID。您可以使用以下命令进行检查:

  • 问题内容: 我将实现类似于Facebook通知和此网站的内容(StackOverflow的通知会通知我们是否有人为我们的问题写评论/答案等)。请注意,用户将使用我的应用程序作为网站而不是移动应用程序。 我遇到以下获取结果的答案,但我需要推送结果而不是获取结果。 根据建议,我在实体类中创建了一个简单方法,并向其中添加了@PostPersist,但此方法不起作用,因此基于此答案,我添加了persist

  • 当我提交表单时,我在浏览器控制台中看到“emit”消息,所以我知道表单提交事件正在触发,但我没有在服务器上收到测试消息。客户端或服务器端似乎什么也没发生,“socket.emit”函数似乎什么也没做。 我做错了什么?

  • 我正在试用netty,但当我响应时,客户端似乎没有收到我的消息。我使用Java NIO和socketChannel编写了相同的代码,看起来很好。我这样说是因为客户机会记录我发送的任何内容。下面是我的服务器 下面是我的服务器处理程序 } 示例响应: 我正在我的盒子上做一个tcpdump,我看到了我在电线上发送的内容,所以我不确定我做错了什么。而且,几分钟后,这会被记录下来,我不确定我在服务器或服务器

  • 我正在通过Spring集成设置一个TCP客户端,以字符串作为有效负载发送消息,不期望返回。也许序列化器/反序列化器不能正常工作?对不起,我正在学习Spring集成。 我可以通过oepnssl连接到外部TCP服务器: 我需要发送的命令是“sessions.list\n。\n”。 现在我构建了一个试图连接到服务器的tcp客户端: spring上下文。xml 因此,在这个repo之后,字符串应该转换为字

  • 问题内容: 所以现在,我正在制作一个基于客户端服务器应用程序的多线程。在服务器端,我为接受的每个连接创建了一个线程。 在线程类中,我创建了一种将命令发送到客户端的方法。我只想要的是如何将参数发送到所有正在运行的客户端?为简单起见,我只想使此服务器向所有连接的客户端发送消息。 我已经阅读了这篇文章,并从此链接中找到方法。但是,当我尝试使用自己的代码时,中没有类似的方法。 好的,这是我的服务器和线程示