Java 由于我想让多个用户制作一个聊天程序,如何从这些代码中添加线程?
java-完成所有客户端的工作Java 由于我想让多个用户制作一个聊天程序,如何从这些代码中添加线程?,java,sockets,networking,network-programming,client-server,Java,Sockets,Networking,Network Programming,Client Server,java-完成所有客户端的工作 package sampleclient; import java.io.*; import java.net.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class SampleClient extends JFrame{ private JTextField userText; private JTextArea chatWindow; priva
package sampleclient;
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SampleClient extends JFrame{
private JTextField userText;
private JTextArea chatWindow;
private ObjectOutputStream user;
private ObjectOutputStream output;
private ObjectInputStream input; //from the server
private String message = "";
private String serverIP;
private Socket connection;
private String name;
private JTextArea contacts;
private PrintWriter toS;
//constructor
public SampleClient(String host, String username){
super("Client");
serverIP = host;
name = username;
userText = new JTextField();
userText.setEditable(false); //not allowed to type while no one is connected
userText.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
sendMessage(event.getActionCommand());
userText.setText("");
}
}
);
add(userText, BorderLayout.SOUTH);
contacts = new JTextArea();
chatWindow = new JTextArea();
add(new JScrollPane(contacts), BorderLayout.EAST); //scroll
contacts.append(" ONLINE CONTACTS \n");
add(new JScrollPane(chatWindow), BorderLayout.CENTER); //scroll
setSize(300, 150);
setVisible(true);
}
//connect to server
public void startRunning(){
try {
connectServer();
setupStreams();
whileChatting();
}catch(EOFException eofException){
showMessage("\n Client terminated connection");
}catch (IOException ioException){
ioException.printStackTrace();
}finally{
closeAll();
}
}
//connectServer
private void connectServer() throws IOException{
showMessage("Attempting connection... \n");
connection = new Socket(InetAddress.getByName(serverIP), 6789); //passes to an IP Adrdress and Port Number
showMessage("Connected to:" + connection.getInetAddress().getHostName()); //prompt
toS = new PrintWriter(connection.getOutputStream(), true);
toS.println(name);
}
//set up streams for sending and receive the messages
private void setupStreams()throws IOException{
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream()); //receive messages
showMessage("\n Streams are connected");
}
//actual chat
private void whileChatting()throws IOException{
ableToType(true);
do{
try{
message = (String) input.readObject();
showMessage("\n" +message);
}catch(ClassNotFoundException classNotFoundException){
showMessage("\n ERROR!");
}
}while(!message.equals("SERVER - END"));
}
//close sockets and streams
private void closeAll(){
showMessage("\n Closing connections..");
ableToType(false);
try{
output.close();
input.close();
connection.close();
}catch(IOException ioException){
ioException.printStackTrace();
}
}
//send messages to server
private void sendMessage(String message){
try{
System.out.println(name);
output.writeObject( "\n" + name + ": " + message);
output.flush(); //push bytes
showMessage("\n" + name + ": " + message);
}catch(IOException ioException){
chatWindow.append("ERROR!");
}
}
//Update chatWindow
private void showMessage(final String m){
SwingUtilities.invokeLater(
new Runnable(){
public void run(){
chatWindow.append(m); //appear at the end of the conversation
}
}
);
}
//permission to type to for user
private void ableToType(final boolean tof){
SwingUtilities.invokeLater(
new Runnable(){
public void run(){
userText.setEditable(tof);
}
}
);
}
}
clientTest.java
package sampleclient;
import javax.swing.*;
public class ClientTest {
public String userName;
private static JFrame frame = new JFrame("Messenger");
private static String getUsername() {
return JOptionPane.showInputDialog(
frame,
"Enter Username:",
"Instant Messenger",
JOptionPane.QUESTION_MESSAGE);
}
public static void main(String[] args){
String username = getUsername();//getting username
SampleClient client;
client = new SampleClient("10.0.1.4", username); //localhost
client.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
client.startRunning();
}
}
java—完成所有服务器的工作
package sampleserver;
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.lang.Object.*;
public class SampleServer extends JFrame{
private JTextField userText; //message variable area
private JTextArea chatWindow; //display the conversation
private ObjectOutputStream output; //output stream->flows from my computer to the other computer
private ObjectInputStream input; //input stream->receive stuff
private ObjectInputStream name; //input stream->receive stuff
private ServerSocket server; //server variable
private Socket connection; //socket variable
private Vector<String> users;
private Vector<String> ips;
private JTextArea conList;
private PrintWriter p;
private BufferedReader fromC;
//constructor
public SampleServer(){
super("Instant Messenger");
userText = new JTextField(); //text field
userText.setEditable(false); //not allowed to type anything if there are no online
userText.addActionListener(
new ActionListener(){
public void actionPerformed (ActionEvent event){
sendMessage(event.getActionCommand()); //sends the message
userText.setText("");
}
}
);
add(userText, BorderLayout.SOUTH);
users = new Vector();
ips = new Vector();
chatWindow = new JTextArea();
conList = new JTextArea();
conList.setEditable(false);
add(new JScrollPane(chatWindow));
add(new JScrollPane(conList), BorderLayout.EAST);
conList.append(" ONLINE USERS \n");
setSize(300, 150);
setVisible(true);
}
//set up and run the server
public void startRunning(){
try {
server = new ServerSocket(6789, 100); //port number and only 100 can connect to the server
while(true){
try{
//connect and have conversation to other client
waitForConnection(); //waiting method
setupStreams(); //set up output and input stream
whileChatting(); //actual chat
}catch(EOFException eofException){
showMessage("\n Server ended the connection!");
}finally {
closeAll();
}
}
}catch(IOException ioException){
ioException.printStackTrace();
}
}
//wait for connection, then display connection information
private void waitForConnection() throws IOException{
showMessage("Waiting for someone to connect...\n");
connection = server.accept(); //once someone asked for connection, accepts this
//showMessage("Now connected to "+connection.getInetAddress().getHostName()); //converts the ip address to string
ips.add(connection.getInetAddress().getHostName()); // adds ip address of client to ips vector
fromC = new BufferedReader(new InputStreamReader(connection.getInputStream())); // gets what client sent through printwriter - username
String s = new String(fromC.readLine()); // saves as string
users.add(s); // saves username of client to users vector
String con = (connection.getInetAddress().getHostName());
showMessage(s + " / " + con + " has connected.");
Iterator c = users.iterator(); // username iterator
Iterator b = ips.iterator(); // ip address iterator
while(c.hasNext()) {
String d = (c.next()).toString(); // gets next element in users vector
String e = (b.next().toString()); // gets next element in ips vector
conList.append(d + "\n"); // displays username in online users list
conList.append("(" + e + ")\n\n"); // displays ip in online users list
}
}
//get stream to send and receive data
private void setupStreams()throws IOException{
output = new ObjectOutputStream(connection.getOutputStream()); //computer who we communicate to
output.flush(); //bytes of information that is send to other person (leftover)
input = new ObjectInputStream(connection.getInputStream()); //receive messages
showMessage("\n Streams are now setup! \n");
}
//actual chat conversation
private void whileChatting() throws IOException{
String message = "You are now connected!";
sendMessage(message);
ableToType(true);
do{
try{
message = (String) input.readObject(); //views it as an object and make sure it's a string
showMessage("\n" + message);
}catch(ClassNotFoundException classNotFoundException){
showMessage("\nError!");
}
}while(!message.equals("CLIENT - END"));
}
//close streams and sockets
private void closeAll(){
showMessage("\n Closing connection... \n");
ableToType(false);
try{
output.close();
input.close();
connection.close();
}catch(IOException ioException){
ioException.printStackTrace();
}
}
//send message to other computer
private void sendMessage(String message){
try{
output.writeObject("SERVER - " +message); //sends the mesage to the output stream
output.flush(); //push extra bytes to user
showMessage("\n SERVER - " + message);
}catch(IOException ioException){
chatWindow.append("\n ERROR!"); //put in the chat area
}
}
//updates chatWindow
private void showMessage(final String text){
SwingUtilities.invokeLater( //updats GUI or threads
new Runnable(){
public void run(){
chatWindow.append(text); //add string at the end of the chatWindow
}
}
);
}
//allow user to type
private void ableToType(final boolean tof){
SwingUtilities.invokeLater( //updats GUI or threads
new Runnable(){
public void run(){
userText.setEditable(tof); //updates the GUI
}
}
);
}
}
问题是我们必须做一个客户端程序,我们做的是有两台笔记本电脑,一台用于打开客户端和服务器,另一台仅用于客户端。两台笔记本电脑已成功连接(客户端-服务器),但装有服务器的笔记本电脑的客户端无法连接到聊天室。但是,如果第二台笔记本电脑的客户端关闭,第一台笔记本电脑可以连接到其服务器。请帮助?问题是您只为一台计算机编程了聊天应用程序,因为它不会为每个客户端创建新的
线程,并进入while循环,直到客户端断开连接
//connect and have conversation to other client
waitForConnection(); //waiting method
setupStreams(); //set up output and input stream
whileChatting(); //actual chat //The problem is here, this should have been in a new Thread
将SampleServer.java更改为:
package sampleserver;
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.lang.Object.*;
public class SampleServer{
private ObjectOutputStream output; //output stream->flows from my computer to the other computer
private ObjectInputStream input; //input stream->receive stuff
private ObjectInputStream name; //input stream->receive stuff
private Socket connection; //socket variable
private String user;
private String ip;
private PrintWriter p;
private BufferedReader fromC;
private serverTest server; //Saves the server test to append messages.
//constructor
public SampleServer(Socket c, String username, String userip, serverTest t){ //EDITED!!
connection = c;
server = t;
ip= userip;
user= username;
setupStreams(); //set up output and input stream
}
public void run() //This method gets called when Thread starts running
{
whileChatting();
closeAll();
}
//get stream to send and receive data
private void setupStreams(){
try{
output = new ObjectOutputStream(connection.getOutputStream()); //computer who we communicate to
output.flush(); //bytes of information that is send to other person (leftover)
input = new ObjectInputStream(connection.getInputStream()); //receive messages
showMessage("\n Streams are now setup! \n");
}catch(IOException ioException){
ioException.printStackTrace();
}
}
//actual chat conversation
private void whileChatting(){
String message = "You are now connected!";
sendMessage(message);
do{
try{
message = (String) input.readObject(); //views it as an object and make sure it's a string
showMessage("\n" + message);
}catch(Exception e){
//showMessage("\nError!");
}
}while(!message.equals("CLIENT - END"));
}
//close streams and sockets
public void closeAll(){
showMessage("\n Closing connection... \n");
try{
output.close();
input.close();
connection.close();
}catch(IOException ioException){
ioException.printStackTrace();
}
}
//send message to other computer
public void sendMessage(String message){
try{
output.writeObject("SERVER - " +message); //sends the mesage to the output stream
output.flush(); //push extra bytes to user
}catch(IOException ioException){
showMessage("\n ERROR!"); //put in the chat area
}
}
//updates chatWindow
private void showMessage(String text){
server.showMessage(text);
}
}
并将serverTest.java更改为:
package sampleserver;
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.lang.Object.*;
public class serverTest extends JFrame {
private JTextField userText; //message variable area
private JTextArea chatWindow; //display the conversation
private ServerSocket server; //server variable
private Vector<String> users;
private Vector<String> ips;
private JTextArea conList;
private ArrayList<SampleServer> connections = new ArrayList<SampleServer>();
public static void main(String[] args){
new serverTest();
}
public serverTest()
{
super("Instant Messenger");
userText = new JTextField(); //text field
userText.addActionListener(
new ActionListener(){
public void actionPerformed (ActionEvent event){
sendMessage(event.getActionCommand()); //sends the message
userText.setText("");
}
}
);
add(userText, BorderLayout.SOUTH);
users = new Vector();
ips = new Vector();
chatWindow = new JTextArea();
conList = new JTextArea();
conList.setEditable(false);
add(new JScrollPane(chatWindow));
add(new JScrollPane(conList), BorderLayout.EAST);
conList.append(" ONLINE USERS \n");
setSize(300, 150);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
try {
server = new ServerSocket(6789, 100); //port number and only 100 can connect to the server
while(true){
try{
showMessage("Waiting for someone to connect...\n");
Socket connection = server.accept(); //once someone asked for connection, accepts this
//showMessage("Now connected to "+connection.getInetAddress().getHostName()); //converts the ip address to string
ips.add(connection.getInetAddress().getHostName()); // adds ip address of client to ips vector
BufferedReader fromC = new BufferedReader(new InputStreamReader(connection.getInputStream())); // gets what client sent through printwriter - username
String s = new String(fromC.readLine()); // saves as string
users.add(s); // saves username of client to users vector
String con = (connection.getInetAddress().getHostName());
showMessage(s + " / " + con + " has connected.");
Iterator c = users.iterator(); // username iterator
Iterator b = ips.iterator(); // ip address iterator
conList.setText("");
while(c.hasNext()) {
String d = (c.next()).toString(); // gets next element in users vector
String e = (b.next().toString()); // gets next element in ips vector
conList.append(d + "\n"); // displays username in online users list
conList.append("(" + e + ")\n\n"); // displays ip in online users list
}
final SampleServer se = new SampleServer(connection, s, con, this);
Thread t = new Thread(new Runnable(){
public void run()
{
se.run();
}
});
connections.add(se);
}catch(EOFException eofException){
showMessage("\n Server ended the connection!");
}
}
}catch(IOException ioException){
ioException.printStackTrace();
}
}
public void closeAll()
{
while (!connections.isEmpty())
{
connections.get(0).closeAll();
connections.remove(0);
}
}
public void sendMessage(String text)
{
showMessage("\n SERVER - " + text);
for (SampleServer s : connections)
{
s.sendMessage(text);
}
}
public void showMessage(final String text)
{
SwingUtilities.invokeLater( //updats GUI or threads
new Runnable(){
public void run(){
chatWindow.append(text); //add string at the end of the chatWindow
}
}
);
}
}
package-sampleserver;
导入java.io.*;
导入java.net。*;
导入java.awt.*;
导入java.awt.event.*;
导入javax.swing.*;
导入java.util.*;
导入java.lang.Object.*;
公共类serverTest扩展了JFrame{
私有JTextField userText;//消息变量区域
私有JTextArea聊天窗口;//显示对话
私有服务器套接字服务器;//服务器变量
专用矢量用户;
专用载体IP;
私人区域控制列表;
私有ArrayList连接=新建ArrayList();
公共静态void main(字符串[]args){
新服务器测试();
}
公共服务器测试()
{
超级(“即时通讯”);
userText=newjtextfield();//文本字段
userText.addActionListener(
新建ActionListener(){
已执行的公共无效操作(操作事件){
sendMessage(event.getActionCommand());//发送消息
userText.setText(“”);
}
}
);
添加(userText,BorderLayout.SOUTH);
用户=新向量();
ips=新向量();
chatWindow=新的JTextArea();
conList=新的JTextArea();
conList.setEditable(false);
添加(新的JScrollPane(聊天窗口));
添加(新的JScrollPane(conList),BorderLayout.EAST);
conList.append(“在线用户”\n);
设置大小(300150);
setDefaultCloseOperation(关闭时退出);
setVisible(真);
试一试{
server=newserversocket(6789100);//端口号,只有100可以连接到服务器
while(true){
试一试{
showMessage(“正在等待某人连接…\n”);
Socket connection=server.accept();//一旦有人请求连接,就接受它
//showMessage(“现在连接到”+connection.getInetAddress().getHostName());//将ip地址转换为字符串
add(connection.getInetAddress().getHostName());//将客户端的ip地址添加到ips向量
BufferedReader fromC=new BufferedReader(new InputStreamReader(connection.getInputStream());//获取客户端通过printwriter发送的内容-用户名
String s=新字符串(fromC.readLine());//另存为字符串
users.add(s);//将客户端的用户名保存到用户向量
字符串con=(connection.getInetAddress().getHostName());
showMessage(s+“/”+con+“已连接”);
迭代器c=users.Iterator();//用户名迭代器
迭代器b=ips.Iterator();//ip地址迭代器
conList.setText(“”);
while(c.hasNext()){
字符串d=(c.next()).toString();//获取用户向量中的下一个元素
字符串e=(b.next().toString());//获取ips向量中的下一个元素
conList.append(d+“\n”);//在联机用户列表中显示用户名
conList.append(“(+e+”)\n\n”);//在联机用户列表中显示ip
}
final SampleServer se=新的SampleServer(连接,s,con,this);
线程t=新线程(新的可运行线程(){
公开募捐
{
se.run();
}
});
连接。添加(se);
}捕获(EOFEException EOFEException){
showMessage(“\n服务器已结束连接!”);
}
}
}捕获(IOException IOException){
ioException.printStackTrace();
}
}
公共空间关闭所有()
{
而(!connections.isEmpty())
{
connections.get(0.closeAll();
连接。移除(0);
}
}
公共无效发送消息(字符串文本)
{
showMessage(“\n服务器-”+文本);
用于(示例服务器:连接)
{
s、 发送消息(文本);
}
}
公共void showMessage(最终字符串文本)
{
SwingUtilities.invokeLater(//更新GUI或线程
新的Runnable(){
公开募捐{
append(text);//在聊天窗口的末尾添加字符串
}
}
);
}
}
在这里,我将GUI代码移到了主类,还将serversocket移到了主类,并使SampleServer只有一个用户。当它收到消息时,它会将其添加到GUI中。
只有服务器可以发送消息,而服务器不向客户端发送用户列表。是什么机制使其能够在多台计算机上工作?@Thufir原始代码没有为每个客户端创建新的线程,因此一次只能为一个客户端服务,因为当客户端连接时,代码进入而循环,直到客户端退出
package sampleserver;
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.lang.Object.*;
public class serverTest extends JFrame {
private JTextField userText; //message variable area
private JTextArea chatWindow; //display the conversation
private ServerSocket server; //server variable
private Vector<String> users;
private Vector<String> ips;
private JTextArea conList;
private ArrayList<SampleServer> connections = new ArrayList<SampleServer>();
public static void main(String[] args){
new serverTest();
}
public serverTest()
{
super("Instant Messenger");
userText = new JTextField(); //text field
userText.addActionListener(
new ActionListener(){
public void actionPerformed (ActionEvent event){
sendMessage(event.getActionCommand()); //sends the message
userText.setText("");
}
}
);
add(userText, BorderLayout.SOUTH);
users = new Vector();
ips = new Vector();
chatWindow = new JTextArea();
conList = new JTextArea();
conList.setEditable(false);
add(new JScrollPane(chatWindow));
add(new JScrollPane(conList), BorderLayout.EAST);
conList.append(" ONLINE USERS \n");
setSize(300, 150);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
try {
server = new ServerSocket(6789, 100); //port number and only 100 can connect to the server
while(true){
try{
showMessage("Waiting for someone to connect...\n");
Socket connection = server.accept(); //once someone asked for connection, accepts this
//showMessage("Now connected to "+connection.getInetAddress().getHostName()); //converts the ip address to string
ips.add(connection.getInetAddress().getHostName()); // adds ip address of client to ips vector
BufferedReader fromC = new BufferedReader(new InputStreamReader(connection.getInputStream())); // gets what client sent through printwriter - username
String s = new String(fromC.readLine()); // saves as string
users.add(s); // saves username of client to users vector
String con = (connection.getInetAddress().getHostName());
showMessage(s + " / " + con + " has connected.");
Iterator c = users.iterator(); // username iterator
Iterator b = ips.iterator(); // ip address iterator
conList.setText("");
while(c.hasNext()) {
String d = (c.next()).toString(); // gets next element in users vector
String e = (b.next().toString()); // gets next element in ips vector
conList.append(d + "\n"); // displays username in online users list
conList.append("(" + e + ")\n\n"); // displays ip in online users list
}
final SampleServer se = new SampleServer(connection, s, con, this);
Thread t = new Thread(new Runnable(){
public void run()
{
se.run();
}
});
connections.add(se);
}catch(EOFException eofException){
showMessage("\n Server ended the connection!");
}
}
}catch(IOException ioException){
ioException.printStackTrace();
}
}
public void closeAll()
{
while (!connections.isEmpty())
{
connections.get(0).closeAll();
connections.remove(0);
}
}
public void sendMessage(String text)
{
showMessage("\n SERVER - " + text);
for (SampleServer s : connections)
{
s.sendMessage(text);
}
}
public void showMessage(final String text)
{
SwingUtilities.invokeLater( //updats GUI or threads
new Runnable(){
public void run(){
chatWindow.append(text); //add string at the end of the chatWindow
}
}
);
}
}