编程实现的思路:在服务器端,首先要启动一条线程用于监听某个指定端口(比如:8000),并且还要再开一条线程用于接收消息,客户端尝试连接该端口(8000),如果成功连接则会返回一个Socket类的实例对象(Socket socket = serversocket.accept();) ,很显然服务器端便应该保存有一个客户列表(比如可以用:ArrayList),使得服务器可以发消息给某个指定的客户端。而客户端在连接服务器之后也应该启动一条线程用于接收消息。当某个客户端进来时,便发送Login消息给服务器,服务器将此消息广播发给当前在线的所有用户,当某个客户端退出时,发送Logout消息给服务器,服务器将此消息广播发给当前在线的所有用户,当客户端之间进行通信时,会发送Talk消息给服务器,服务器再将此消息转发给指定的客户端,也就是所有的通信都是通过服务器进行转发的。
主要的代码实现如下:
服务器端:
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import javax.swing.JScrollBar;
public class ChatServer extends javax.swing.JFrame {
ArrayList<User> list = new ArrayList<User>();
static String local;
int port = 8000;
boolean isNomalexit = false;
Mythread jtThread;
public ChatServer() {
initComponents();
this.setTitle("服务器");
this.setResizable(false);
this.setLocationRelativeTo(null);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
dispose();
}
});
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { } //开始监听按钮的事件
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) { } //停止监听按钮的事件
class Mythread extends Thread{ } //负责监听端口8000的线程
class ClientThread extends Thread{ } //负责接收消息的线程
public void sendtoclient(User user,String message){ } //发送消息message给用户,user为发送者
public void sendtoallclient(User user,String message){ } //发送消息message给所有用户,user发送者
public void removeuser(User user){ }
public static void main(String args[]) throws UnknownHostException {
local = InetAddress.getLocalHost().getHostAddress();
ChatServer frame = new ChatServer();
frame.setVisible(true);
}
客户端:
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import javax.swing.JScrollBar;
public class ChatClient extends javax.swing.JFrame {
Socket s;
boolean isExit = false;
DataInputStream in;
PrintStream out;
ArrayList<String> list =new ArrayList<String>();
static String name;
ReceivemessageThread thread;
public ChatClient() {
initComponents();
this.setTitle("客户端");
this.setResizable(false);
this.setLocationRelativeTo(null);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
if(s!=null){
sendmessage("Logout " + name);
try {
isExit = true;
in.close();
out.close();
s.close();
} catch (IOException ex) {
Logger.getLogger(ChatClient.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
});
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt){ } //登录按钮的事件
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt){ } //发送按钮的事件
class ReceivemessageThread extends Thread{ } // 接收消息的线程
public void sendmessage(String message){ } //发送消息
public void removeuser(String name){ } //移除在线列表上的用户名
public static void main(String args[]) {
ChatClient frame = new ChatClient();
frame.setVisible(true);
}
运行演示:
在做完这个程序之后,对于网络编程也算是基本上入门了,后续还会有很多的通信程序,因为这门课的要求就是做一个类似QQ的通信程序,写下这篇博客也算是记录自己的学习进程。