Java 一个简单的客户机/服务器聊天程序
我正在尝试使用java创建一个简单的聊天程序,它包含to表单、客户端表单和服务器表单,客户端表单包含一个文本字段和一个按钮(发送按钮),服务器表单包含一个文本区域 当我点击send按钮时,它应该将TextField中写入的文本发送到服务器表单中的TextArea 这是第一次,但当我第二次点击按钮时,它就不起作用了 这是我在服务器表单中使用的代码:Java 一个简单的客户机/服务器聊天程序,java,netbeans,Java,Netbeans,我正在尝试使用java创建一个简单的聊天程序,它包含to表单、客户端表单和服务器表单,客户端表单包含一个文本字段和一个按钮(发送按钮),服务器表单包含一个文本区域 当我点击send按钮时,它应该将TextField中写入的文本发送到服务器表单中的TextArea 这是第一次,但当我第二次点击按钮时,它就不起作用了 这是我在服务器表单中使用的代码: public class Server extends javax.swing.JFrame implements Runnable { p
public class Server extends javax.swing.JFrame implements Runnable {
private Thread th;
public Server() {
initComponents();
th = new Thread(this);
th.start();
}
// The main method was here
@Override
public void run() {
// Etablir la connexion
try {
ServerSocket ecoute;
ecoute = new ServerSocket(1111);
Socket service = null;
System.out.println("Serveur en attente d'un client !");
while (true) {
service = ecoute.accept();
System.out.println("Client connécté !");
DataInputStream is = new DataInputStream(service.getInputStream());
jTextArea1.setText("Client dit : "+ is.readUTF().toUpperCase());
service.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
这是客户表单的代码:
public class Client extends javax.swing.JFrame {
DataOutputStream os;
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
try {
os.writeUTF(jTextField1.getText());
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE,null, ex);
}
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
Client c = new Client();
c.setVisible(true);
try {
Socket s = new Socket("localhost", 1111);
c.os = new DataOutputStream(s.getOutputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
在
服务器代码的while(true)
部分中,您在读取一次套接字后正在关闭它,而在客户端,您不会重新打开一个套接字(以及一个新的输入流
)。我建议您在while(true)
部分中有另一个循环,它将继续读取和显示新数据,直到达到EOF。您的问题在于服务器的代码:
要在服务器端接收来自不同客户端的各种消息,
对于每个接受,即每个客户端,您必须创建一个线程来处理其请求,因为您使用的是TCP连接。(-每个接受只处理一个请求,然后关闭连接)
我清理了与代码套接字无关的部分(即,一些与客户端GUI相关的不完整部分),因此我提供了一个不同的版本,可以很好地用于许多同时进行的客户端连接,并且您可以看到所有到达服务器的消息,而不仅仅是第一条消息
服务器代码:
import java.io.*;
import java.net.*;
public class Server {
public static void run() {
try
{
ServerSocket ecoute;
ecoute = new ServerSocket(1111);
Socket service = null;
System.out.println("serveur en attente d'un client!");
while(true)
{
service = ecoute.accept();
System.out.println("client connécté!");
// ##call a new thread
WorkerThread wt = new WorkerThread(service);
wt.start();
}
}
catch(IOException e)
{
e.printStackTrace();
}
}
public static void main(String args[]) {
run();
}
}
class WorkerThread extends Thread {
Socket service;
WorkerThread(Socket service) {
this.service = service;
}
public void run() {
boolean flag=true; //you can change this flag's condition, to test if the client disconects
try
{
while (flag){
DataInputStream is = new DataInputStream(service.getInputStream());
System.out.println("client dit: " + is.readUTF().toUpperCase());
}
service.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
import java.io.*;
import java.io.*;
import java.net.*;
import java.util.logging.*;
public class Client {
DataOutputStream os;
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
Client c = new Client();
try {
Socket s = new Socket("localhost", 1111);
c.os = new DataOutputStream(s.getOutputStream());
while (true){
String str = Input.read_string();
c.os.writeUTF(str);
}
} catch ( IOException e) {
// TODO auto-generated catch block
e.printStackTrace();
}
}
});
}
}
public class Input{
public static String read_string(){
String read="";
try{
read = new BufferedReader(new InputStreamReader(System.in), 1).readLine();
}catch (IOException ex){
System.out.println("error reading from the input stream!");
}
return read;
}
}
客户代码:
import java.io.*;
import java.net.*;
public class Server {
public static void run() {
try
{
ServerSocket ecoute;
ecoute = new ServerSocket(1111);
Socket service = null;
System.out.println("serveur en attente d'un client!");
while(true)
{
service = ecoute.accept();
System.out.println("client connécté!");
// ##call a new thread
WorkerThread wt = new WorkerThread(service);
wt.start();
}
}
catch(IOException e)
{
e.printStackTrace();
}
}
public static void main(String args[]) {
run();
}
}
class WorkerThread extends Thread {
Socket service;
WorkerThread(Socket service) {
this.service = service;
}
public void run() {
boolean flag=true; //you can change this flag's condition, to test if the client disconects
try
{
while (flag){
DataInputStream is = new DataInputStream(service.getInputStream());
System.out.println("client dit: " + is.readUTF().toUpperCase());
}
service.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
import java.io.*;
import java.io.*;
import java.net.*;
import java.util.logging.*;
public class Client {
DataOutputStream os;
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
Client c = new Client();
try {
Socket s = new Socket("localhost", 1111);
c.os = new DataOutputStream(s.getOutputStream());
while (true){
String str = Input.read_string();
c.os.writeUTF(str);
}
} catch ( IOException e) {
// TODO auto-generated catch block
e.printStackTrace();
}
}
});
}
}
public class Input{
public static String read_string(){
String read="";
try{
read = new BufferedReader(new InputStreamReader(System.in), 1).readLine();
}catch (IOException ex){
System.out.println("error reading from the input stream!");
}
return read;
}
}
在此之后,您可能知道,您需要将所有到达服务器的消息发送到聊天室中的所有客户端。“第一次它可以工作,但当我第二次单击按钮时它就不工作了。”。那么接下来会发生什么呢?具体一点。@Lion不会发生任何事情,它会做任何事情,似乎只有当ENO异常被记录时,动作事件才会起作用?这似乎很奇怪。我不知道我必须在哪里使用另一个while(true)loop他不需要重新打开客户端的套接字,因为他正在使用TCP。他需要在服务器端继续处理消息,而在服务器端进行一个简单的while(true)循环是不够的,因为它只支持一个客户端。。。