1. 程式人生 > >簡單的tcp與udp通訊 java程式碼

簡單的tcp與udp通訊 java程式碼

在網路程式設計中,有UDP與TCP這麼兩種協議,其主要的區別是TCP是安全的,不會丟失資料包,但效率比較低;UDP是不安全的,其容易丟失資料包,但是傳輸的效率比較高。在顯示的應用中,不涉及money的傳輸一般都是使用UDP的,下面我將使用java程式碼編寫簡單的UDP與TCP通訊的例子;

(1)UDP

UDP通訊的時候,客戶端往伺服器傳送訊息時是不需要確認伺服器端是否存在或者工作是否正常的,它只管傳送,不管反饋。

客戶端程式碼如下:

package socket;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public class UdpClient {
	public static void main(String[] args) {
		DatagramSocket datagramSocket = null;
		try {
			datagramSocket = new DatagramSocket();
			String str = "我是客戶端,要傳送訊息";
			byte[] buf = str.getBytes();
			int port = 8080;//伺服器端的埠
			String ip = "10.20.59.197";//伺服器端的ip地址
			DatagramPacket datagramPacket = new DatagramPacket(buf, buf.length, InetAddress.getByName(ip), port);
			datagramSocket.send(datagramPacket); 
			System.out.println("給服務端傳送資料");
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(datagramSocket != null){
				datagramSocket.close();
			}
		}
		
	}
}

關閉socket連線最好在finally中進行,以防止發生異常。此時沒有伺服器端時,啟動客戶端也不會報任何錯誤。


伺服器端程式碼如下:

package socket;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class UdpServer {
	public static void main(String[] args) {
		int port = 8080;
		DatagramSocket datagramSocket = null;
		try {
			datagramSocket = new DatagramSocket(port);
			byte[] buf = new byte[1024];
			DatagramPacket datagramPacket = new DatagramPacket(buf, buf.length);
			datagramSocket.receive(datagramPacket);
			String str = new String(datagramPacket.getData(), 0, datagramPacket.getLength());
			System.out.println("接收到客戶端的資料:" + str);
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(datagramSocket != null){
				datagramSocket.close();
			}
		}
		
	}
}

(2)TCP

TCP通訊的時候,客戶端往伺服器傳送訊息時需要進行三次“握手”操作,以確保伺服器端正常。

客戶端程式碼如下:

package socket;


import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;


public class TcpClient {
	public static void main(String[] args) {
		Socket socket = null;
		
String ip = "10.20.59.197"; int port = 8080; try { //ip:伺服器端的ip地址,port:伺服器端的埠 socket = new Socket(ip, port); OutputStream outputStream = socket.getOutputStream(); String str = "我是客戶端,請求向伺服器傳送請求"; byte[] buf = str.getBytes(); outputStream.write(buf); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if(socket != null){ try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } }

此時如果在沒有伺服器端的情況下啟動客戶端是會報異常,異常資訊如下:



這個異常表示,伺服器端不正常工作,無法接收客戶端傳送的資料,所以在TCP通訊時需要先開啟伺服器端;


伺服器端程式碼如下:


package socket;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class TcpServer {
	public static void main(String[] args) {
		int port = 8080;
		ServerSocket serverSocket = null;
		try {
			serverSocket = new ServerSocket(port);
			//伺服器端開啟後,會一直在port這個埠上等待,直到有客戶端請求連線
			Socket accept = serverSocket.accept();
			InputStream inputStream = accept.getInputStream();
			byte[] buf = new byte[1024];
			int length = inputStream.read(buf);
			String str = new String(buf, 0, length);
			System.out.println("接收到客戶端的訊息:" + str);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(serverSocket != null){
				try {
					serverSocket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
	}
}

serverSocket.accept()這個方法是阻塞的,正式的環境中,這邊應該是個死迴圈,然後每次有客戶端連線上之後,伺服器就啟動一個執行緒來處理這個客戶端的任務,而自己則會繼續去port這個埠上等待下一個客戶端連線,這邊我寫的比較簡單。



以上是自己的一些見解,如有錯誤,歡迎指正,謝謝!!