TCP
TCP協(xié)議是面向連接、保證高可靠性(數(shù)據(jù)無丟失、數(shù)據(jù)無失序、數(shù)據(jù)無錯誤、數(shù)據(jù)無重復(fù)到達(dá))傳輸層協(xié)議。
TCP通過三次握手建立連接,通訊完成時要拆除連接,由于TCP是面向連接的所以只能用于端到端的通訊。
Socket
Socket可以說是一種針對網(wǎng)絡(luò)的抽象,應(yīng)用通過它可以來針對網(wǎng)絡(luò)讀寫數(shù)據(jù)。根據(jù)TCP協(xié)議和UDP協(xié)議的不同,在網(wǎng)絡(luò)編程方面就有面向兩個協(xié)議的不同socket,一個是面向字節(jié)流的一個是面向報文的。
對socket的本身組成倒是比較好理解。既然是應(yīng)用通過socket通信,肯定就有一個服務(wù)器端和一個客戶端。所以它必然就包含有一個對應(yīng)的IP地址。另外,在這個地址上server要提供一系列的服務(wù),于是就需要有一系列對應(yīng)的窗口來提供服務(wù)。所以就有一個對應(yīng)的端口號(Port)。
Socket服務(wù)端
Server端所要做的事情主要是建立一個通信的端點(diǎn),然后等待客戶端發(fā)送的請求。典型的處理步驟如下:
1. 構(gòu)建一個ServerSocket實(shí)例,指定本地的端口。這個socket就是用來監(jiān)聽指定端口的連接請求的。
2.重復(fù)如下幾個步驟:
a. 調(diào)用socket的accept()方法來獲得客戶端的連接請求。通過accept()方法返回的socket實(shí)例,建立了一個和客戶端的新連接。
b.通過這個返回的socket實(shí)例獲取InputStream和OutputStream,可以通過這兩個stream來分別讀和寫數(shù)據(jù)。
c.結(jié)束的時候調(diào)用socket實(shí)例的close()方法關(guān)閉socket連接。
服務(wù)端示例代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
|
public class TestTCPSend {
public static void main(String[]
args) {
ServerSocket serverSocket=null;
Socket socket=null;
String msg="hello client,I am server..";
try {
//構(gòu)造ServerSocket實(shí)例,指定端口監(jiān)聽客戶端的連接請求
serverSocket=new ServerSocket(8080);
//建立跟客戶端的連接
socket=serverSocket.accept();
//向客戶端發(fā)送消息
OutputStream os=socket.getOutputStream();
os.write(msg.getBytes());
InputStream is=socket.getInputStream();
//接受客戶端的響應(yīng)
byte[] b=new byte[1024];
is.read(b);
System.out.println(new String(b));
} catch (IOException e) {
e.printStackTrace();
} finally {
//操作結(jié)束,關(guān)閉socket
try {
serverSocket.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
|
Socket客戶端
客戶端的請求過程稍微有點(diǎn)不一樣:
1.構(gòu)建Socket實(shí)例,通過指定的遠(yuǎn)程服務(wù)器地址和端口來建立連接。
2.通過Socket實(shí)例包含的InputStream和OutputStream來進(jìn)行數(shù)據(jù)的讀寫。
3.操作結(jié)束后調(diào)用socket實(shí)例的close方法,關(guān)閉。
服務(wù)端示例代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
|
public class TestTCPReceive {
public static void main(String[]
args) {
Socket socket=null;
try {
//對服務(wù)端發(fā)起連接請求
socket=new Socket("localhost",
8080);
//接受服務(wù)端消息并打印
InputStream is=socket.getInputStream();
byte b[]=new byte[1024];
is.read(b);
System.out.println(new String(b));
//給服務(wù)端發(fā)送響應(yīng)信息
OutputStream os=socket.getOutputStream();
os.write("yes,I have received you message!".getBytes());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
|
運(yùn)行測試:
先運(yùn)行服務(wù)端代碼,之后運(yùn)行客戶端。
之后可以分別在客戶端和服務(wù)端看到對應(yīng)的消息。
|