[英]multiclient java client server chat
我正在尝试编写多客户端服务器聊天记录。 一切都应该在同一台计算机上运行,每个客户端在不同的Shell终端控制台中。 我在这边读了几个线程,有人说,我应该为每个连接的客户端在服务器上运行新线程。 因此,这就是我要做的。仍然,服务器正在从其控制台上的每个客户端打印消息,但是客户端只能看到他们编写的消息,而不能看到聊天中提交的每个消息。 我该怎么解决?
这是代码:服务器:
//package javauj.serwer;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class Server {
private static final int PORT_NUM = 5051;
private static ServerSocket serS;
private static Socket s;
public static void main(String[] args) throws IOException{
DateFormat df = new SimpleDateFormat("dd/MM/yy HH:mm:ss");
Calendar cal = Calendar.getInstance();
System.out.println(df.format(cal.getTime())+" Server waiting on port "+PORT_NUM);
try {
serS = new ServerSocket(PORT_NUM);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while(true){
try {
s = serS.accept();
System.out.println("New user connected");
ServerThread st=new ServerThread(s);
st.start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
服务器线程:
import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Scanner;
public class ServerThread extends Thread {
Socket socket=null;
private Scanner sc;
private PrintStream ps;
public ServerThread(Socket s) {
this.socket=s;
}
public void run(){
DateFormat df = new SimpleDateFormat("dd/MM/yy HH:mm:ss");
Calendar cal = Calendar.getInstance();
String response;
while(true){
try {
sc = new Scanner(socket.getInputStream());
ps = new PrintStream(socket.getOutputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if((response=sc.nextLine())!=null){
System.out.println(df.format(cal.getTime())+" Napisal "+response);
ps.println(df.format(cal.getTime())+" Napisal :"+response);
}
}
}
}
和客户
import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class Client {
static Scanner sc;
static Scanner sc2;
static Socket s;
static String response;
public static void main(String[]args) throws UnknownHostException, IOException{
String send;
sc=new Scanner(System.in); //client send scanner
s = new Socket("127.0.0.1", 5051);
sc2 = new Scanner(s.getInputStream()); //client response scanner
PrintStream ps = new PrintStream(s.getOutputStream());
while(true){
System.out.println(">");
send = sc.nextLine();
ps.println(send);
// I tried run new thread for responses
//Thread thread = new Thread(new Runnable(){
//public void run(){
//while(true){
response=sc2.nextLine();
System.out.println(response);
// }
//}
//});
}
}
}
客户端需要两个线程:
第一个线程(来自服务器的读取器)仅读取传入消息并将其打印到控制台
第二个线程(服务器的写程序)接受用户输入并将其发送到服务器。
实际上,在您的代码中,客户端(主线程)上只有一个线程。
您必须实现ServerThread实例与服务器之间的通信(例如通过接口)。 必须通知服务器ServerThread获取的消息,然后将此消息转换为其他(先前已建立的)套接字(必须对其进行跟踪)。
您的客户端有两个Scanner,但是其中一个实际上阻止了nextLine()调用中的另一个。 因此,您必须在单独的线程中运行扫描器之一。
以下代码对我有用,但必须考虑线程安全性:
public interface MessageListener {
void acceptMessage(String message);
}
public class Server {
private static final int PORT_NUM = 5051;
private static ServerSocket serS;
private static List<PrintStream> sockets = new ArrayList<PrintStream>();
public static void main(String[] args) throws IOException{
DateFormat df = new SimpleDateFormat("dd/MM/yy HH:mm:ss");
Calendar cal = Calendar.getInstance();
System.out.println(df.format(cal.getTime())+" Server waiting on port "+PORT_NUM);
try {
serS = new ServerSocket(PORT_NUM);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
MessageListener listener = new MessageListener() {
@Override
public void acceptMessage(String message) {
Iterator<PrintStream> it = sockets.iterator();
while (it.hasNext()) {
PrintStream ps = it.next();
ps.println("Have got message: " + message);
}
}
};
while(true){
try {
Socket s = serS.accept();
sockets.add(new PrintStream(s.getOutputStream()));
System.out.println("New user connected");
ServerThread st=new ServerThread(s, listener);
st.start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class ServerThread extends Thread {
Socket socket=null;
private Scanner sc;
//private PrintStream ps;
private final MessageListener listener;
public ServerThread(Socket s, MessageListener listener) {
this.socket=s;
this.listener = listener;
}
public void run(){
DateFormat df = new SimpleDateFormat("dd/MM/yy HH:mm:ss");
Calendar cal = Calendar.getInstance();
String response;
while(true){
try {
sc = new Scanner(socket.getInputStream());
//ps = new PrintStream(socket.getOutputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if((response=sc.nextLine())!=null){
System.out.println(df.format(cal.getTime())+" Napisal "+response);
//ps.println(df.format(cal.getTime())+" Napisal :"+response);
listener.acceptMessage(response);
}
}
}
}
public class Client {
static Scanner sc;
static Scanner sc2;
static Socket s;
static String response;
public static void main(String[]args) throws UnknownHostException, IOException{
String send;
sc=new Scanner(System.in); //client send scanner
s = new Socket("127.0.0.1", 5051);
ResponseListener l = new ResponseListener(new Scanner(s.getInputStream()));
Thread t = new Thread(l);
t.start();
PrintStream ps = new PrintStream(s.getOutputStream());
while(true){
System.out.println(">");
send = sc.nextLine();
ps.println(send);
}
}
static class ResponseListener implements Runnable {
private final Scanner scanner;
ResponseListener(Scanner scanner) {
this.scanner = scanner;
}
@Override
public void run() {
while (true) {
response = scanner.nextLine();
System.out.println(response);
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.