提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助檔案
文章目錄
- 前言
- 一、Tcp編程
- 1.為什么需要Socket進行網路通信?
- 2.Socket簡介
- 二、服務端程序
- 1.操作的程序
- 2.分步驟編程
- 三、客戶端程序
- 1.操作的程序
- 2.分步驟編程
- 四、總結
前言
一、Tcp編程
計算機網路是指兩臺或更多的計算機組成的網路,在同一個網路中,任意兩臺計算機都可以直接通信,因為所有計算機都需要遵循同一種網路協議,
那什么是互聯網呢?互聯網是網路的網路(internet),即把很多計算機網路連接起來,形成一個全球統一的互聯網,
對某個特定的計算機網路來說,它可能使用網路協議ABC,而另一個計算機網路可能使用網路協議XYZ,如果計算機網路各自的通訊協議不統一,就沒法把不同的網路連接起來形成互聯網,因此,為了把計算機網路接入互聯網,就必須使用TCP/IP協議,
TCP/IP協議泛指互聯網協議,其中最重要的兩個協議是TCP協議和IP協議,只有使用TCP/IP協議的計算機才能夠聯入互聯網,使用其他網路協議(例如NetBIOS、AppleTalk協議等)是無法聯入互聯網的,
先來演示一下效果,看下圖:

在開發網路應用程式的時候,我們又會遇到Socket這個概念,Socket是一個抽象概念,一個應用程式通過一個Socket來建立一個遠程連接,而Socket內部通過TCP/IP協議把資料傳輸到網路:

Socket、TCP和部分IP的功能都是由作業系統提供的,不同的編程語言只是提供了對作業系統呼叫的簡單的封裝,例如,Java提供的幾個Socket相關的類就封裝了作業系統提供的介面,
1.為什么需要Socket進行網路通信?
因為僅僅通過IP地址進行通信是不夠的,同一臺計算機同一時間會運行多個網路應用程式,例如瀏覽器、QQ、郵件客戶端等,當作業系統接收到一個資料包的時候,如果只有IP地址,它沒法判斷應該發給哪個應用程式,所以,作業系統抽象出Socket介面,每個應用程式需要各自對應到不同的Socket,資料包才能根據Socket正確地發到對應的應用程式,
2.Socket簡介
一個Socket就是由IP地址和埠號(范圍是0~65535)組成,可以把Socket簡單理解為IP地址加埠號,埠號總是由作業系統分配,它是一個0~65535之間的數字,其中,小于1024的埠屬于特權埠,需要管理員權限,大于1024的埠可以由任意用戶的應用程式打開,
使用Socket進行網路編程時,本質上就是兩個行程之間的網路通信,其中一個行程必須充當服務器端,它會主動監聽某個指定的埠,另一個行程必須充當客戶端,它必須主動連接服務器的IP地址和指定埠,如果連接成功,服務器端和客戶端就成功地建立了一個TCP連接,雙方后續就可以隨時發送和接收資料,
因此,當Socket連接成功地在服務器端和客戶端之間建立后:
- 對服務器端來說,它的Socket是指定的IP地址和指定的埠號;
- 對客戶端來說,它的Socket是它所在計算機的IP地址和一個由作業系統分配的隨機埠號,

二、服務端程序
1.操作的程序
對于服務端而言,該操作步驟有5步:
- 先創建一個服務端的套接字
- 等待客戶端的鏈接
- 獲取socket通信的輸入流
- 獲取socket通道的輸出流
- 關閉serverSocket通道
結果圖
2.分步驟編程
- 先創建一個服務端的套接字
ServerSocket serverSocket = new ServerSocket(8888);
- 等待客戶端的鏈接
Socket socket = serverSocket.accept();
- 獲取socket通信的輸入流
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
- 獲取socket通道的輸出流
bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
- 關閉serverSocket通道
serverSocket.close();
所有服務端代碼:
package Chat;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
//如果一個類需要有界面的顯示,該類需要繼承JFram
//1.定義JFram表單中的組件
//2.在構造方法初始化表單的組件
//3.使用網路編程實作資料的傳輸(TCP,UDP協議)
//4.實作"發送"按鈕的監聽事件
public class ServerChatMain extends JFrame implements ActionListener{
public static void main(String[] args) throws Exception {
//
new ServerChatMain();//呼叫構造方法
}
//屬性
//文本域
private JTextArea jta;
//滾動條
private JScrollPane jsp;
//面板
private JPanel jp;
//文本框
private JTextField jtf;
//按鈕
private JButton jb;
//行為
//輸出流
private BufferedWriter bw = null;
//構造方法
public ServerChatMain() throws IOException {
//初始化組件
jta = new JTextArea();
//設定文本與不可編輯
jta.setEditable(false);
//注意:需要將文本框添加到滾動條中,實作滾動效果
jsp = new JScrollPane(jta);
//面板
jp = new JPanel();
//文本框
jtf = new JTextField(10);
//按鈕
jb = new JButton("發送");
//注意:需要將文本框與按鈕添加到面板中
jp.add(jtf);
jp.add(jb);
//注意:需要將滾動條與面板全部添加到表單中
this.add(jsp, BorderLayout.CENTER);//放在中間
this.add(jp,BorderLayout.SOUTH);//放在最下面,上北下南
//注意:需要設定標題,大小,位置,關閉,是否可見
this.setTitle("QQ聊天服務端");
this.setSize(300,300);
this.setLocation(300,300);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
/*******************Tcp服務端開始*********************/
//給發送按鈕系結一個監聽點擊事件
jb.addActionListener(this);//繼承一個借口ActionListener
try{
// 1.創建一個服務端的套接字
ServerSocket serverSocket = new ServerSocket(8888);
//
// 2.等待客戶端的鏈接
Socket socket = serverSocket.accept();
// 3.獲取socket通信的輸入流
//InputStream in = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = null;
// 4.獲取socket通道的輸出流
bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
//
//回圈獲取物件
while((line = br.readLine())!=null){
//將文本域的資料拼接到文本域中顯示
jta.append(line+System.lineSeparator());
}
// 5.關閉serverSocket通道
serverSocket.close();
}catch (Exception e){
e.printStackTrace();
}
/*******************Tcp服務端開始*********************/
}
@Override
public void actionPerformed(ActionEvent e) {
// System.out.println("fafa");
//1.獲取文本框中發送的內容
String text = jtf.getText();
//2.拼接需要發送的資料內容
text = "服務端對客戶端說:"+text;
// 3.自己也需要顯示
jta.append(text+System.lineSeparator());
try{
//4.發送
bw.write(text);
bw.newLine();
bw.flush();
//5.清空文本框內容
jtf.setText("");
}catch (IOException e1){
e1.printStackTrace();
}
}
}
三、客戶端程序
1.操作的程序
對于客戶端而言,該操作步驟有5步:
- 先創建一個客戶端的套接字
- 獲取socket通信的輸入流
- 獲取socket通道的輸出流
- 關閉serverSocket通道
結果圖:

2.分步驟編程
- 先創建一個客戶端的套接字
Socket socket = new Socket("127.0.0.1",8888);
- 獲取socket通信的輸入流
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
- 獲取socket通信的輸出流
bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
- 關閉serverSocket通道
socket.close();
所有代碼:
package Chat;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
//如果一個類需要有界面的顯示,該類需要繼承JFram
//1.定義JFram表單中的組件
//2.在構造方法初始化表單的組件
public class ClientChatMain extends JFrame implements ActionListener{
public static void main(String[] args) {
//
new ClientChatMain();//呼叫構造方法
}
//屬性
//文本域
private JTextArea jta;
//滾動條
private JScrollPane jsp;
//面板
private JPanel jp;
//文本框
private JTextField jtf;
//按鈕
private JButton jb;
//行為
//定義輸出流
private BufferedWriter bw = null;
//構造方法
public ClientChatMain(){
//初始化組件
jta = new JTextArea();
//設定文本與不可編輯
jta.setEditable(false);
//注意:需要將文本框添加到滾動條中,實作滾動效果
jsp = new JScrollPane(jta);
//面板
jp = new JPanel();
//文本框
jtf = new JTextField(10);
//按鈕
jb = new JButton("發送");
//注意:需要將文本框與按鈕添加到面板中
jp.add(jtf);
jp.add(jb);
//注意:需要將滾動條與面板全部添加到表單中
this.add(jsp, BorderLayout.CENTER);//放在中間
this.add(jp,BorderLayout.SOUTH);//放在最下面,上北下南
//注意:需要設定標題,大小,位置,關閉,是否可見
this.setTitle("QQ聊天客戶端");
this.setSize(300,300);
this.setLocation(300,300);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
/*******************Tcp服務端開始*********************/
//給發送按鈕系結一個監聽事件
jb.addActionListener(this);
try{
// 1.創建一個客戶端的套接字(嘗試鏈接)
Socket socket = new Socket("127.0.0.1",8888);
// 2.獲取socket通信的輸入流
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 3.獲取socket通道的輸出流
bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
//回圈讀取資料,并拼接到文本域中
String line = null;
while((line = br.readLine())!=null){
jta.append(line+System.lineSeparator());
}
// 4.關閉socket通道
socket.close();
}catch (Exception e){
e.printStackTrace();
}
/*******************Tcp服務端開始*********************/
}
@Override
public void actionPerformed(ActionEvent e) {
//1.獲取文本框中需要發送的資料內容
String text = jtf.getText();
//2.拼接內容
text = "客戶端對服務端說:" + text;
//3.自己顯示
jta.append(text+System.lineSeparator());
try{
//4.發送
bw.write(text);
bw.newLine();
bw.flush();
//5.清空文本框內容
jtf.setText("");
}catch (Exception e2){
e2.printStackTrace();
}
}
}
四、總結
整體的對話要求已經實作,但是還需要進一步的改進,正常的回車鍵也可以直接發送,下一章會實作給大家,請繼續關注,
mac版本的圖案就是不粗,哈哈哈!

記錄時間:2020年11月22日
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/226850.html
標籤:其他
下一篇:計算機網路五層模型(ing)
