(二)網路程式設計:聊天室(1)
概述:通過網路程式設計來實現聊天室功能
第一步:建立服務端與客戶端並建立連線
服務端:
import java.io.IOException;
import java.net.ServerSocket;
public class Server {
ServerSocket server;
public Server() {
try {
server=new ServerSocket(8888);
} catch (IOException e) {
e.printStackTrace();
}
}
public void start() {
try {
System.out.println("等待連線...");
server.accept();
System.out.println("連線成功!");
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Server server=new Server();
server.start();
}
}
客戶端:
import java.io.IOException;
import java.net.Socket;
public class Client {
Socket socket;
public Client() {
try {
socket=new Socket("localhost",8888);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Client client=new Client();
}
}
注:輸出語句為了測試連線,服務端的埠號範圍為05-29775,且執行時需先執行服務端後再執行客戶端。
第二步:既然要做聊天室,那就必須上點檔次,如果只是在控制檯進行輸入輸出,那也太low了,所以我們可以將客戶端做成一個有訊息顯示框與訊息輸入框的窗體,但是服務端是沒有必要的,因為服務端僅僅起到了一個轉發的功能,所以服務端是否窗體化並不重要。
客戶端:
import java.awt.BorderLayout;
import java.io.IOException;
import java.net.Socket;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class Client extends JFrame{
private Socket socket;
private JPanel panel;
private JTextArea MsgShow;
private JTextArea MsgSend;
public Client() {
try {
socket=new Socket("localhost",8888);
panel=new JPanel();
MsgShow=new JTextArea(15,42);
MsgSend=new JTextArea(5,42);
inIt();
} catch (IOException e) {
e.printStackTrace();
}
}
public void inIt() {
this.setSize(500,415);//設定窗體大小
this.setLocationRelativeTo(null);//窗體居中
this.setResizable(false);//設定窗體不可拉伸
this.setLayout(new BorderLayout());//設定窗體佈局
this.add(panel,BorderLayout.CENTER);//將面板新增到窗體中
//給資訊顯示與傳送區域新增滾動條
JScrollPane jspMsgShow=new JScrollPane(MsgShow);
JScrollPane jspMsgSend=new JScrollPane(MsgSend);
//設定垂直滾動條,常數VERTICAL_SCROLLBAR_ALWAYS:始終垂直滾動
jspMsgShow.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
jspMsgSend.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
//設定資訊顯示區為不可編輯
MsgShow.setEditable(false);
//設定資訊輸入區行滿自動換行
MsgSend.setLineWrap(true);
//將資訊顯示與傳送區新增至面板中
panel.add(jspMsgShow);
panel.add(jspMsgSend);
//設定窗體關閉即退出
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
//設定窗體可見
this.setVisible(true);
}
}
注:若要關閉程式,僅關閉客戶端視窗是不可以的,需要在程式控制臺處將客戶端與服務端全部關閉。
第三步:為資訊編輯區新增鍵盤事件,使得在資訊編輯完後點擊回車鍵釋放回車鍵之後資訊傳送至伺服器端,然後將文字輸入區域內的資料清空,由此我們可知,第一,需要新增鍵盤事件,第二,需要資訊傳送方法
客戶端:
import java.awt.BorderLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class Client extends JFrame{
public void start() {
KeyListener key=new KeyAdapter() {
public void keyReleased(KeyEvent e) {
String str=sendMsg.getText();
if(e.getKeyCode()==KeyEvent.VK_ENTER) {
sendMessage(str);
}
}
};
sendMsg.addKeyListener(key);
}
public void sendMessage(String str) {
if(str==""||str.trim().length()==0) {
return;
}
try {
PrintWriter pw=new PrintWriter(new OutputStreamWriter(socket.getOutputStream(),"UTF-8"),true);
str=str.trim();
pw.println(str);
sendMsg.setText("");
} catch (IOException e) {
e.printStackTrace();
}
sendMsg.setText("");
}
public static void main(String[] args) {
Client client=new Client();
client.start();
}
}
第四步:現在客戶端的資訊可以傳送給客戶端,如果想要資訊顯示在客戶端接受資訊處,那就需要服務端接收到客戶端發來的資訊之後再發送至客戶端後客戶端再將資訊顯示在資訊顯示處
服務端:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
ServerSocket server;
public Server() {
try {
server=new ServerSocket(8888);
} catch (IOException e) {
e.printStackTrace();
}
}
public void start() {
try {
Socket socket=server.accept();
System.out.println("連線成功!");
BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8"));
PrintWriter pw=new PrintWriter(new OutputStreamWriter(socket.getOutputStream(),"UTF-8"),true);
String Read="";
while((Read=br.readLine())!=null) {
pw.println(Read);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Server server=new Server();
server.start();
}
}
客戶端:
import java.awt.BorderLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class Client extends JFrame{
private Socket socket;
private JPanel panel;
private JTextArea showMsg;
private JTextArea sendMsg;
public Client() {
try {
socket=new Socket("localhost",8888);
panel=new JPanel();
showMsg=new JTextArea(15,42);
sendMsg=new JTextArea(5,42);
inIt();
} catch (IOException e) {
e.printStackTrace();
}
}
public void start() {
KeyListener key=new KeyAdapter() {
public void keyReleased(KeyEvent e) {
String str=sendMsg.getText();
if(e.getKeyCode()==KeyEvent.VK_ENTER) {
sendMessage(str);
}
}
};
sendMsg.addKeyListener(key);
try {
BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8"));
String backMsg="";
while((backMsg=br.readLine())!=null) {
showMsg.append(backMsg+"\n");
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
public static void main(String[] args) {
Client client=new Client();
client.start();
}
}