Java 多客户端聊天服务器

Java 多客户端聊天服务器,java,sockets,chat,Java,Sockets,Chat,因此,我对Java中的网络仍然是新手,其中大部分都是令人困惑的,特别是线程服务器。大约两周前,我制作了一个简单的Socket聊天程序,但我想扩展它,但在局域网上有多个客户端和自动服务器检测(通过广播或手动ping每个ip/端口)。但本周我主要关注多客户机,也就是多线程服务器。这是到目前为止我所掌握的代码,但它有缺陷,服务器只向第二个客户端发送/接收消息,而第一个客户端只能发送一条消息,而服务器却忽略了它。我的目标是让这个服务器支持大约10-20个客户端 package org.codinglla

因此,我对Java中的网络仍然是新手,其中大部分都是令人困惑的,特别是线程服务器。大约两周前,我制作了一个简单的Socket聊天程序,但我想扩展它,但在局域网上有多个客户端和自动服务器检测(通过广播或手动ping每个ip/端口)。但本周我主要关注多客户机,也就是多线程服务器。这是到目前为止我所掌握的代码,但它有缺陷,服务器只向第二个客户端发送/接收消息,而第一个客户端只能发送一条消息,而服务器却忽略了它。我的目标是让这个服务器支持大约10-20个客户端

package org.codingllamas.Chat;

import java.awt.Toolkit;
import java.io.*;
import java.net.*;

import javax.swing.text.BadLocationException;
import javax.swing.text.html.HTML;

public class SC {

static Socket clientSocket;
static BufferedReader inFromServer;
static BufferedWriter outToServer;

public static void clientSetup(int port,String ip) throws IOException, BadLocationException {
     String incomingSentence;
     Start.kit.insertHTML(Start.doc,Start.doc.getLength(),"<b>Connected to </b>" + ip + ":" + port + "<br>",0,0,HTML.Tag.B);
     clientSocket = new Socket(ip,port);
     while (true) {
         inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
         incomingSentence = inFromServer.readLine();     
         Toolkit.getDefaultToolkit().beep();
         Start.window.requestFocus();
         Start.kit.insertHTML(Start.doc,Start.doc.getLength(),"<b>Server: </b>" + incomingSentence + "<br>",0,0,HTML.Tag.B);
     }
}

public static void clientSend(String msg) throws IOException, BadLocationException{
    outToServer = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
    outToServer.write(msg + "\r\n");
    outToServer.flush();
    outToServer.write(msg + "\r\n");
    outToServer.flush();
    Start.kit.insertHTML(Start.doc,Start.doc.getLength(),"<b>You: </b>" + msg + "<br>",0,0,HTML.Tag.B);
}

static ServerSocket welcomeSocket;
static Socket connectionSocket;
static BufferedReader inFromClient;
static BufferedWriter outToClient;

public static void secondClient() throws IOException{

    connectionSocket = welcomeSocket.accept();


}

public static void serverSetup(int port) throws Exception {
    welcomeSocket = new ServerSocket(port);
    Start.kit.insertHTML(Start.doc,Start.doc.getLength(),"<b>Server Started on port: " + port + "</b><br>",0,0,HTML.Tag.B);
    connectionSocket = welcomeSocket.accept();
    new Thread(new Runnable(){
        public void run(){
            try {
                secondClient();
            } catch (IOException e) {
                System.out.println("Cannot send message");
                e.printStackTrace();
            }
        }
    }).start();
    String clientSentence;
    while(true){       
        inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
        clientSentence = inFromClient.readLine();
        Toolkit.getDefaultToolkit().beep();
        Start.window.requestFocus();
        Start.kit.insertHTML(Start.doc,Start.doc.getLength(),"<b>Parther: </b>" + inFromClient.readLine() + "<br>",0,0,HTML.Tag.B);
   }
}

public static void serverSend(String msg) throws IOException, BadLocationException {
    outToClient = new BufferedWriter(new OutputStreamWriter(connectionSocket.getOutputStream()));
    outToClient.write(msg + "\r\n");
    outToClient.flush();
    Start.kit.insertHTML(Start.doc,Start.doc.getLength(),"<b>You: </b>" + msg + "<br>",0,0,HTML.Tag.B);
}
}
package org.codingllamas.Chat;
导入java.awt.Toolkit;
导入java.io.*;
导入java.net。*;
导入javax.swing.text.BadLocationException;
导入javax.swing.text.html.html;
公开课理学士{
静态套接字clientSocket;
静态缓冲阅读器信息服务器;
静态缓冲写入程序输出到服务器;
publicstaticvoidclientsetup(int-port,stringip)抛出IOException、BadLocationException{
串入句;
Start.kit.insertHTML(Start.doc,Start.doc.getLength(),“连接到”+ip+:“+port+”
”,0,0,HTML.Tag.B); clientSocket=新套接字(ip,端口); while(true){ INFOROMSERVER=new BufferedReader(新的InputStreamReader(clientSocket.getInputStream()); IncomingSession=INFOROMSERVER.readLine(); getDefaultToolkit().beep(); Start.window.requestFocus(); Start.kit.insertHTML(Start.doc,Start.doc.getLength(),“服务器:”+incomingSession+“
”,0,0,HTML.Tag.B); } } 公共静态void clientSend(字符串msg)引发IOException、BadLocationException{ outToServer=new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()); outToServer.write(msg+“\r\n”); outToServer.flush(); outToServer.write(msg+“\r\n”); outToServer.flush(); Start.kit.insertHTML(Start.doc,Start.doc.getLength(),“You:”+msg+“
”,0,0,HTML.Tag.B); } 静态服务器插座; 静态插座连接插座; 静态缓冲阅读器; 静态缓冲写入程序输出到客户端; public static void secondClient()引发IOException{ connectionSocket=welcomeSocket.accept(); } 公共静态void服务器设置(int端口)引发异常{ welcomeSocket=新服务器套接字(端口); Start.kit.insertHTML(Start.doc,Start.doc.getLength(),“服务器在端口上启动:“+port+”
”,0,0,HTML.Tag.B); connectionSocket=welcomeSocket.accept(); 新线程(newrunnable()){ 公开募捐{ 试一试{ secondClient(); }捕获(IOE异常){ System.out.println(“无法发送消息”); e、 printStackTrace(); } } }).start(); 字符串介词句; 虽然(正确){ INFOROMCLIENT=new BufferedReader(新的InputStreamReader(connectionSocket.getInputStream()); ClientSession=inFromClient.readLine(); getDefaultToolkit().beep(); Start.window.requestFocus(); Start.kit.insertHTML(Start.doc,Start.doc.getLength(),“Parther:”+INFOROMCLIENT.readLine()+“
”,0,0,HTML.Tag.B); } } 公共静态void serverSend(字符串msg)引发IOException、BadLocationException{ outToClient=new BufferedWriter(new OutputStreamWriter(connectionSocket.getOutputStream()); outToClient.write(msg+“\r\n”); outToClient.flush(); Start.kit.insertHTML(Start.doc,Start.doc.getLength(),“You:”+msg+“
”,0,0,HTML.Tag.B); } }
因为您希望能够拥有多个客户端,所以应该创建一个线程,主要目的是等待和接受连接

接下来,您可能应该为客户机提供一个对象,这样他们就可以轻松地存储套接字并将其放入数组中。在这个客户机对象中,您可以创建用于发送和接收数据的线程,以及各个客户机的输入/输出流


这将使您的程序可以扩展到多个客户端,并使处理所有客户端变得更容易。

并非所有方法都应该是静态的,您应该利用java的面向对象功能。让人们发现代码中的错误并不是特别有效的。您应该使用调试器(或添加打印语句)来隔离问题,方法是跟踪程序的进度,并将其与预期发生的情况进行比较。一旦这两个问题出现分歧,你就发现了问题所在。(然后,如果有必要,您应该构建一个。)我将如何实现这一点?我知道您可以使用hashmap来存储客户机号码和与之相关的线程。但是我如何向所有客户发送消息呢?我不知道在某个特定的服务器上发送(访问一个方法)thread@DarkLlama如果您有一个包含输出流的客户机对象,那么只需遍历所有客户机对象的数组并调用客户机类中的方法将数据写入其输出流即可。