1、Tcp
tcp協議:是一種固定連線爲基礎的協議,提供兩臺計算機之間可靠的數據傳送。
工作原理:3次握手
1、客戶端發送鏈接請求,創建一個socket
2、服務端接受請求。並創建新的Socket
3、兩個Socket建立專線連接
創建服務端步驟:
1、創建一個socket,使用函數soket()
2、設置socket屬性,使用函數setsockopt();
3、綁定ip地址、端口等信息到soket上,使用函數bind();
4、開啓監聽,使用函數listen();
5、接受客戶端上來的連接,使用函數accept();
7、關閉網絡連接。關閉監聽。
創建客戶端的步驟:
1、創建一個socket,用函數socket();
2、設置socket屬性,用函數setsockopt();
3、綁定IP地址、端口等信息到socket上,用函數bind();
4、設置要連接的對方的IP地址和端口等屬性;
5、連接服務器,用函數connect();
6、收發數據,用函數send()和recv(),或者read()和write();
7、關閉網絡連接;
代碼部分:
Server服務端:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* TCP的服務器端
* 1、創建一個socket來監聽客戶端請求
* 2、接收客戶端的請求
* 3、交互數據
*
* Tcp Socket:流式套接字(通信是通過IO流來進行)
*/
public class Server {
public static void main(String[] args) throws IOException {
//1、創建socket來監聽請求。這個ServerSocket只是用於監聽客戶端請求。
/* port:端口號
* 1、端口號的取值範圍:0-65535
* 2、在我們的應用程序開發中,一般使用1024之後的端口號。
* 3、一個端口號只能被一個應用程序使用。
* 4、通過socket發送的消息,必須要指定端口號來接收。
*/
ServerSocket socket = new ServerSocket(8888);
//開始監聽客戶端的連接請求
/* 1、accept()方法,接收客戶端的請求。
* 2、accept()方法是一個阻塞方法,當程序運行到這裏的時候,
* 會阻塞在這裏。一直到有客戶端的連接請求到來。
* 3、accept()方法接收到客戶端請求後,會返回一個socket對象。
* 這個socket對象就是一次通信的連接(後面的通信都使用這個socket)
*/
Socket sock = socket.accept();
//發送消息
/* 1、發送消息需要使用IO流
* 2、消息方向:從內存中將詳細發送到網絡-->使用輸出流
* 3、sock.getOutputStream(),獲取socket中的輸出流,通過這個流向網絡發送消息
*/
OutputStream os = sock.getOutputStream();
os.write("歡迎連接XXX服務器".getBytes());
//接收消息,使用輸入流。和讀文件操作基本一致
InputStream is = sock.getInputStream();
byte[] buf = new byte[1024];
int num = is.read(buf);
String str = new String(buf,0,num);
System.out.println("接收到客戶端消息:"+str);
//通信結束,關閉socket
socket.close();
sock.close();
}
}
Client客戶端:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* TCP的客戶端
* 1、向服務器發起連接請求
*
*/
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
//向服務器發起連接請求
/* 參數:127.0.0.1-->服務器的IP地址
* 參數:8888-->服務器的端口號(必須和服務器指定監聽的端口號一致)
*/
Socket sock = new Socket("127.0.0.1", 8888);
//接收消息
InputStream is = sock.getInputStream();
byte[] buf = new byte[1024];
int num = is.read(buf);//讀取到的數據長度
String str = new String(buf,0,num);
//發送消息
OutputStream os = sock.getOutputStream();
os.write("你好服務器!".getBytes());
//通信結束後,關係socket
sock.close();
}
}
先啓動服務端後啓動客戶端,否則會拋異常
運行結果:
2、Udp
udp協議:它是無連接通信協議,不保證數據的可靠傳輸,但能同時向多個目標發送數據,也能接受自多個源的數據,它是獨立發送數據包方式進行的(對數據要求不高的場合,效率較快安全性差)
創建服務端步驟:
1、創建一個socket,使用函數socket();
2、設置socket屬性,用函數setsocket();
3、綁定ip地址、端口等信息到soket上,用函數bind();
4、循環接受數據,用函數recefrom();
5、關閉網絡連接;
創建客戶端步驟:
1、創建一個socket,用函數socket();
2、設置socket屬性,用函數setsockopt();* 可選
3、綁定IP地址、端口等信息到socket上,用函數bind();
4、設置對方的IP地址和端口等屬性;
5、發送數據,用函數sendto();
6、關閉網絡連接;
代碼部分
發送端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
/**
* UDP的發送端
* 1、創建一個UDP的socket(數據報套結字)
* 2、創建發送的數據包(信+信封)
* 3、發送
* 4、關閉socket
*/
public class Sender {
public static void main(String[] args) throws IOException {
//參數8888,表示本地所使用的端口號
DatagramSocket sock = new DatagramSocket(8888);
/* 參數1:需要發送的內容(byte數組)
* 參數2:發送消息的長度(byte數組的長度)
* 參數3:InetAddress,目的地的地址。
* 參數4:接收端的端口號。(不是本地端口號)
*/
byte[] buf = "UDP所發送的消息".getBytes();
DatagramPacket dp = new DatagramPacket(buf, buf.length,
InetAddress.getByName("127.0.0.1"), 8887);
//3、發送
sock.send(dp);
//4、
sock.close();
}
}
接收端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
/**
* UDP接收端
* 1、創建UDP套接字
* 2、創建一個接收消息的數據包
* 3、接收消息。接收到的所有消息都被放在了數據包中(dp中)
*/
public class Recver {
public static void main(String[] args) throws IOException {
//1
DatagramSocket sock = new DatagramSocket(8887);
/* 參數1:接收的消息放入到buf數組
* 參數2:最多接收多長的消息
*/
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
//3.receive方法是一個阻塞方法。如果沒有接收到消息,會一直阻塞在這裏。一直到接收到消息爲止
sock.receive(dp);
//4、將消息轉換成String並輸出
/* DatagramPacket中方法的說明:
* 1、getData():獲取接收到的消息內容
* 2、dp.getLength():獲取實際接收到的消息長度
* 3、dp.getPort():發送方的端口號(如果要回消息,使用這個端口)
* 4、dp.getAddress():發送放的網絡地址(回消息的地址)
*/
String str = new String(dp.getData(),0,dp.getLength());
System.out.println("接收到來自:"+str);
}
}
先發送,再接收
3、socket
原理:通信的兩端都有Socket
網絡通信其實就是Socket間的通信
數據在兩個Socket間通過某種協議下的IO流傳輸