1. 程式人生 > 其它 >Java學習筆記(21)——網路程式設計(套接字)、TCP、UDP、簡易聊天程式

Java學習筆記(21)——網路程式設計(套接字)、TCP、UDP、簡易聊天程式

技術標籤:Java學習欄目網路socketjava網路通訊網路協議

網路程式設計(套接字)

跟網路相關的操作實質都是資料傳輸。
通過IO流在網路上實現資料傳輸。
	網路模型---物理層---資料鏈路層---網路層---傳輸層(TCP/UDP)---會話層---表示層---應用層
IP地址---確定主機在網路世界中的位置。
	分類 IPV4 四位0-255來組成 
		IPV6四位16進位制的數
埠---用於和計算機外界進行資料互動的媒介。
埠號---埠的標記 0-65535來表示。
域名---域名可以和IP地址進行一一對映。

IP和埠

package com.hst.netio;
import
java.net.InetSocketAddress; /** * InetSocketAddress * 1代表IP * 1地址和埠號的類 * @author Administrator * */ public class InetSocketAddressDemo { public static void main(String[] args) { //建立代表IP和埠號的類的物件 InetSocketAddress is = new InetSocketAddress("www.baidu.com",8090); System.out.println(
is.getAddress().toString());//IP地址 System.out.println(is.getHostName().toString());//主機名 System.out.println(is.getPort());//埠號 } }

UDP和TCP

UDP和TCP兩者過程不一樣

UDP:過程類似於寄送快遞 需要有自己的快遞點(套接字物件)再有包裹(資料包物件)包裹還要有自己的標記(埠標記包裹本身,IP地址,寄送的物件)所有的包裹打包及寄送的過程都由快遞點(套接字物件)來完成。

UDP

資料接收端

package com.hst.netio;
import java.io.
IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetSocketAddress; import java.net.SocketException; /** * 1接收發送端傳送的內容 * 1接收端要監聽資料包的埠號 * 1建立接收資料的資料包 * 1埠是接收資料的連結 * 1資料傳輸先發送 * @author Administrator * */ public class UDPjieshouDemo { public static void main(String[] args) throws IOException { //建立套接字物件 相當於建立一個快遞點 來接收寄送的快遞 要接收寄送的快遞 就要知道快遞的編號 即監聽埠號 DatagramSocket ds = new DatagramSocket(9090); //建立接收資料的資料包 //接收端要有位元組來接收資料 DatagramPacket dp = new DatagramPacket(new byte[1024],1024); ds.receive(dp);//接收資料 ds.close();//關流 //解析資料包 System.out.println(dp.getAddress()); System.out.println(dp.getPort()); System.out.println(new String(dp.getData(),0,dp.getLength())); } }

資料傳送端

package com.hst.netio;
import java.io.IOException;
/**
 * 1基於IO流
 * 1傳輸資料時不會建立連結
 * 1不可靠的傳輸方式 不可靠 不安全
 * 1傳輸速度快
 * 1底層根據資料包進行資料的傳輸 資料包的最大值不能超過 64KB
 * 1適合傳輸的場景 直播 語音 視訊等
 * 1DatagramSocket DatagramPacket
 * 1用於UDP
 * 0步驟
 * 1建立套接字物件   相當於是成立一個快遞寄送點
 * 2建立資料包       相當於是打包一個包裹 要求有包裹的內容 包裹的寄送目的地 和寄送點 埠號可以作為包裹的標記 地址名是寄送地點
 * 3傳送資料包       相當於是從快遞點寄送包裹
 * 4關流
 * @author Administrator
 *
 */
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
public class UDPfasongDemo {
 public static void main(String[] args) throws SocketException {
  //建立套接字物件
  DatagramSocket ds = new DatagramSocket();
  //建立資料包
  //第一個引數要傳送的資料
  //轉換為位元組陣列 預設為位元組流
  //可以傳輸的資料的位元組個數
  //制定地址和埠號
  DatagramPacket dp = new DatagramPacket("hello".getBytes(),"hello".length(),new InetSocketAddress("localhost",9090));
  //傳送資料包
  try {
   ds.send(dp);
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  ds.close();//關流
 }
    //
}

基於UDP的簡易聊天程式

package com.hst.netio;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.util.Scanner;
/**
 * 1用來建立一個微型的資料傳輸的聊天室
 * 1需要結合線程來實現
 * 1一直髮送 一直接收
 * 1知道傳送者和接收端
 * @author Administrator
 *
 */
public class MiniChatDemo {
 public static void main(String[] args) {
  new Thread(new ChatSentDemo(),"傳送者").start();
  new Thread(new Receiv(),"接收者").start();
 }
}
//用來代表執行緒傳送的類
class ChatSentDemo implements Runnable{
 //
 public synchronized void run() {
  //
   try {
    //建立套接字物件
    DatagramSocket ds = new DatagramSocket();
    Scanner sc = new Scanner(System.in);
    //
    while(true) {//一直髮送的狀態;
     byte[] data = sc.next().getBytes();
     //建立資料包
     DatagramPacket dp = new DatagramPacket(data,data.length,new InetSocketAddress("127.0.0.1",9091));
     ds.send(dp);
    }
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  //
 }
}
//代表執行緒接收的類
class Receiv implements Runnable {	
 public synchronized void run() {
  //建立套接字物件
  try {
   DatagramSocket ds = new DatagramSocket(9091);
   while(true) {
   DatagramPacket dp = new DatagramPacket(new byte[1024],1024);
   ds.receive(dp);
   System.out.println("收到來自"+dp.getAddress()+"的訊息"+new String(dp.getData(),0,dp.getLength()));
   }
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
}

TCP:過程類似於打有線電話 首先我們需要建立電話線路 (套接字物件)電話線路的連結需要兩個條件 對方的位置(IP)唯一獨特的線路(埠)通過電話線路給對方傳送訊息(套接字物件自帶的IO流)當我們打通電話的時候 需要通知對方 即電話響鈴。

package com.hst.netio;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import org.omg.CORBA.portable.OutputStream;
public class TCPServerDemo {
 public static void main(String[] args) throws IOException{
  //建立伺服器端物件---監聽埠
  //建立伺服器端物件---監聽埠
  ServerSocket ss= new ServerSocket(9092);//這是一個寄送站 
  //接受連線
  Socket s=ss.accept(); //阻塞
  //while(true);
  System. out .println(1);
  //接受客戶端傳送資料
  //獲取自帶的位元組輸入流
  InputStream is=s.getInputStream();
  //自建緩衝區
  byte[]bs= new byte[10];
  //
  int len=-1;
  while((len=is.read(bs))!=-1){ //阻塞
  //輸出每次讀到的內容
  System. out .println( new String(bs,0,len));
  }
  //通知客戶端資料已經接受完畢
  s.shutdownInput();
  //獲取自帶的位元組輸出流給客戶端傳送資料
  java.io.OutputStream os = s.getOutputStream();
  os.write( "你也好".getBytes());
  //通知客戶端資料已經發生完畢
  s.shutdownOutput();
  //關流
  ss.close();
  }
}
package com.hst.netio;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import org.omg.CORBA.portable.OutputStream;
/**
 * 1基於io
 * 1可靠安全
 * 1傳輸速度慢
 * 1不根據資料包傳輸資料 沒有大小限制
 * 1使用場景 聊天 檔案 
 * @author Administrator
 *
 */
public class TCPClientDemo {
 public static void main(String[]args) throws IOException{
  //建立客戶端物件
  Socket s = new Socket();//建立一個電話裝置
  //建立連線---阻塞
  s.connect( new InetSocketAddress( "127.0.0.1",9092));//建立一條專屬的線路 並連結特定使用者的標記
  //while(true);
  //往伺服器端傳送資料
  //獲取自帶的位元組輸出流 預設往伺服器端寫資料
  java.io.OutputStream os = s.getOutputStream();//
  //通過自帶的輸出流寫出資料
  os.write( "您好".getBytes()); //阻塞
  /*for(inti=0;i<=100000;i++){
  os.write("a".getBytes());
  System.out.println(i);
  }*/
  //通知伺服器端資料已經寫完
  s.shutdownOutput();//將信件內容傳送出去 
  //接受伺服器端傳送的資料
  InputStream is=s.getInputStream();
  byte[] bs= new byte[10];
  int len=-1;
  while((len=is.read(bs))!=-1){
  System. out .println( new String(bs,0,len));
  }
  //通知伺服器端資料已經接受完畢
  s.shutdownInput();//告訴伺服器 收到回信
  //關流
  s.close();
  }
}