日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java学习笔记-网络编程

發(fā)布時間:2024/4/15 java 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java学习笔记-网络编程 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Java提供了網(wǎng)絡編程,并且在實際中有著大量運用

網(wǎng)絡編程

網(wǎng)絡編程概述

  • 網(wǎng)絡模型
    OSI參考模型
    TCP/IP參考模型

  • 網(wǎng)絡通訊要素
    IP地址
    端口號
    傳輸協(xié)議

網(wǎng)絡參考模型

網(wǎng)絡通訊要素

  • IP地址:InetAddress
    網(wǎng)絡中設備的標識
    不易記憶,可用主機名
    本地回環(huán)地址:127.0.0.1 主機名:localhost
InetAddress ia = InetAddress.getByName("www.baidu.com"); System.out.println("address : " + ia.getHostAddress()); System.out.println("name : " + ia.getHostName());
  • 端口號
    用于標識進程的邏輯地址,不同進程的標識
    有效端口:065535,其中01024系統(tǒng)使用或保留端口

  • 傳輸協(xié)議
    通訊的規(guī)則
    常見協(xié)議:TCP,UDP

TCP和UDP

  • UDP
    將數(shù)據(jù)及源和目的封裝成數(shù)據(jù)包中,不需要建立連接
    每個數(shù)據(jù)報的大小在限制在64k內(nèi)
    因無連接,是不可靠協(xié)議
    不需要建立連接,速度快

  • TCP
    建立連接,形成傳輸數(shù)據(jù)的通道
    在連接中進行大數(shù)據(jù)量傳輸
    通過三次握手完成連接,是可靠協(xié)議
    必須建立連接,效率會稍低

Socket

  • Socket就是為網(wǎng)絡服務提供的一種機制
  • 通信的兩端都有Socket
  • 網(wǎng)絡通信其實就是Socket間的通信
  • 數(shù)據(jù)在兩個Socket間通過IO傳輸

UDP傳輸

發(fā)送端與接收端是兩個獨立的運行程序

  • DatagramSocket與DatagramPacket
  • 建立發(fā)送端,接收端
  • 建立數(shù)據(jù)包
  • 調用Socket的發(fā)送接收方法
  • 關閉Socket

發(fā)送端

在發(fā)送端,要在數(shù)據(jù)包對象中明確目的地 IP 及端口

DatagramSocket ds = new DatagramSocket(); byte[] by = "hello,udp".getBytes(); DatagramPacket dp = new DatagramPacket(by, 0, by.length, InetAddress.getByName("127.0.0.1"), 10000); ds.send(dp); ds.close();

接收端

在接收端,要指定監(jiān)聽的端口

DatagramSocket ds = new DatagramSocket(10000); byte[] by = new byte[1024]; DatagramPacket dp = new DatagramPacket(by, by.length); ds.receive(dp); String str = new String(dp.getData(), 0, dp.getLength()); System.out.println(str + "---" + dp.getAddress()); ds.close();

基于UDP的聊天程序

import java.io.*; import java.net.*; class Send implements Runnable {private DatagramSocket ds;public Send(DatagramSocket ds) {this.ds = ds;}public void run() {try {BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));String line = null;while((line = bufr.readLine()) != null) {byte[] buf = line.getBytes();DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.1.255"), 10002);ds.send(dp);if("886".equals(line))break;}} catch (Exception e) {throw new RuntimeException("發(fā)送端失敗");}} }class Rece implements Runnable {private DatagramSocket ds;public Rece(DatagramSocket ds) {this.ds = ds;}public void run() {try {while(true) {byte[] buf = new byte[1024];DatagramPacket dp = new DatagramPacket(buf, buf.length);ds.receive(dp);String ip = dp.getAddress().getHostAddress();String data = new String(dp.getData(), 0, dp.getLength());if("886".equals(data)) {System.out.println(ip + "...離開聊天室");break;}System.out.println(ip + ":" + data);}} catch (Exception e) {throw new RuntimeException("接收端失敗");}} }class Test {public static void main(String[] args) throws Exception {DatagramSocket sendSocket = new DatagramSocket();DatagramSocket receSocket = new DatagramSocket(10002);new Thread(new Send(sendSocket)).start();new Thread(new Rece(receSocket)).start();} }

TCP傳輸

  • Socket和ServerSocket
  • 建立客戶端和服務器端
  • 建立連接后,通過Socket中的IO流進行數(shù) 據(jù)的傳輸
  • 關閉socket同樣,客戶端與服務器端是兩個獨立的應用程序

基本思路(客戶端)

  • 客戶端需要明確服務器的ip地址以及端口,這樣才可以去試著建立連接,如果連接失敗,會出現(xiàn)異常
  • 連接成功,說明客戶端與服務端建立了通道,那么通過IO流就可以進行數(shù)據(jù)的傳輸,而Socket對象已經(jīng)提供了輸入流和輸出流對象,通過getInputStream(),getOutputStream()獲取即可
  • 與服務端通訊結束后,關閉Socket

客戶端

通過Socket建立對象并指定要連接的服務端主機以及端口

Socket s = new Socket(192.168.1.1, 9999); OutputStream out = s.getOutputStream(); out.write("hello".getBytes()); s.close();

基本思路(服務端)

  • 服務端需要明確它要處理的數(shù)據(jù)是從哪個端口進入的
  • 當有客戶端訪問時,要明確是哪個客戶端,可通過accept()獲取已連接的客戶端對象,并通過該對象與客戶端通過IO流進行數(shù)據(jù)傳輸
  • 當該客戶端訪問結束,關閉該客戶端

服務端

建立服務端需要監(jiān)聽一個端口

ServerSocket ss = new ServerSocket(9999); Socket s = ss.accept (); InputStream in = s.getInputStream(); byte[] buf = new byte[1024]; int num = in.read(buf); String str = new String(buf,0,num); System.out.println(s.getInetAddress().toString() + ":" + str); s.close(); ss.close();

基于TCP的發(fā)送返回示例

import java.net.*; import java.io.*;class TcpClient {public static void main(String[] args) throws IOException {Socket s = new Socket("192.168.1.2",10004);OutputStream out = s.getOutputStream();out.write("Client Test".getBytes());InputStream in = s.getInputStream();byte[] buf = new byte[1024];int len = in.read();System.out.printf(new String(buf,0,len));s.close();} }class TcpServer {public static void main(String[] args) throws IOException {ServerSocket ss = new ServerSocket(10004);Socket s = ss.accept();String ip = s.getInetAddress().getHostAddress();System.out.printf(ip + "···connected");InputStream in = s.getInputStream();byte[] buf = new byte[1024];int len = in.read(buf);System.out.printf(new String(buf, 0 ,len));OutputStream out = s.getOutputStream();out.write("Server Get MSG".getBytes());s.close();ss.close();} }

Tcp傳輸最容易出現(xiàn)的問題

  • 客戶端連接上服務端,兩端都在等待,沒有任何數(shù)據(jù)傳輸
  • 通過例程分析:
    因為read方法或者readLine方法是阻塞式
  • 解決辦法:
    自定義結束標記
    使用shutdownInput,shutdownOutput方法
import java.io.*; import java.net.*;class TransClient {public static void main(String[] args) throws Exception {Socket s = new Socket("192.168.1.2", 10005);//定義讀取鍵盤數(shù)據(jù)的流對象。BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));//定義目的,將數(shù)據(jù)寫入到socket輸出流。發(fā)給服務端//BufferedWriter bufOut = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));PrintWriter out = new PrintWriter(s.getOutputStream(),true);//定義一個socket讀取流,讀取服務端返回的大寫信息BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));String line = null;while((line = bufr.readLine()) != null) {if("over".equals(line))break;out.println(line); //此行直接替代以下三行//bufOut.write(line);//bufOut.newLine();//bufOut.flush();String str =bufIn.readLine();System.out.println("server:"+str);}bufr.close();s.close();} }class TransServer {public static void main(String[] args) throws Exception {ServerSocket ss = new ServerSocket(10005);Socket s = ss.accept();String ip = s.getInetAddress().getHostAddress();System.out.println(ip + "···connected");//讀取socket讀取流中的數(shù)據(jù)。BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));//socket輸出流。將大寫數(shù)據(jù)寫入到socket輸出流,并發(fā)送給客戶端//BufferedWriter bufOut = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));PrintWriter out = new PrintWriter(s.getOutputStream(),true);String line = null;while((line = bufIn.readLine()) != null) {System.out.println(line);out.println(line.toUpperCase()); //此行直接替代以下三行//bufOut.write(line.toUpperCase());//bufOut.newLine();//bufOut.flush();}s.close();ss.close();} }

TCP的并發(fā)

當A客戶端連接上以后。被服務端獲取到。服務端執(zhí)行具體流程,這時B客戶端連接,只有等待
因為服務端還沒有處理完A客戶端的請求,還有循環(huán)回來執(zhí)行下次accept方法。所以暫時獲取不到B客戶端對象
那么為了可以讓多個客戶端同時并發(fā)訪問服務端,服務端最好就是將每個客戶端封裝到一個單獨的線程中,這樣,就可以同時處理多個客戶端請求
示例:并發(fā)上傳文件

import java.io.*; import java.net.*; class PicClient {public static void main(String[] args) throws Exception {if(args.length != 1) {System.out.println("請選擇一個jpg格式的圖片");return ;}File file = new File(args[0]);if(!(file.exists() && file.isFile())) {System.out.println("該文件有問題,要么不存在,要么不是文件");return ;}if(!file.getName().endsWith(".jpg")) {System.out.println("圖片格式錯誤,請重新選擇");return ;}if(file.length() > 1024 * 1024 * 5) {System.out.println("文件過大,請重新選擇");return ;}Socket s = new Socket("192.168.1.2",10007);FileInputStream fis = new FileInputStream(file);OutputStream out = s.getOutputStream();byte[] buf = new byte[1024];int len = 0;while((len = fis.read(buf)) != -1) {out.write(buf,0,len);}//告訴服務端數(shù)據(jù)已寫完s.shutdownOutput();InputStream in = s.getInputStream();byte[] bufIn = new byte[1024];int num = in.read(bufIn);System.out.println(new String(bufIn, 0, num));fis.close();s.close();} }class PicThread implements Runnable {private Socket s;PicThread(Socket s) {this.s = s;}public void run() {int count = 1;String ip = s.getInetAddress().getHostAddress();try {System.out.println(ip + "···connected");InputStream in = s.getInputStream();File dir = new File("d:\\pic");File file = new File(dir, ip + "(" + (count) + ")" + ".jpg");while(file.exists())file = new File(dir, ip + "(" + (count++) + ")" + ".jpg");FileOutputStream fos = new FileOutputStream(file);byte[] buf = new byte[1024];int len = 0;while((len = in.read(buf)) != -1) {fos.write(buf,0,len);}OutputStream out = s.getOutputStream();out.write("上傳成功".getBytes());fos.close();s.close();} catch (Exception e) {throw new RuntimeException(ip+"上傳失敗");}} }class PicServer {public static void main(String[] args) throws Exception {ServerSocket ss = new ServerSocket(10007);while(true) {Socket s = ss.accept();new Thread(new PicThread(s)).start();}} }

URI

Uniform Resource Identifies(統(tǒng)一資源定位符)

import java.net.*; class Test {public static void main(String[] args) throws MalformedURLException {URL url = new URL("http://192.168.1.2/web/index.html?name=cj&age=20");System.out.println("getProtocol() :" + url.getProtocol());System.out.println("getHost() :" + url.getHost());System.out.println("getPort() :" + url.getPort());System.out.println("getPath() :" + url.getPath());System.out.println("getFile() :" + url.getFile());System.out.println("getQuery() :" + url.getQuery());URLConnection conn = url.openConnection();System.out.println(conn);InputStream in = conn.getInputStream();byte[] buf = new byte[1024];int len = in.read(buf);System.out.println(new String(buf, 0, len));} }

轉載于:https://www.cnblogs.com/cj5785/p/10664831.html

總結

以上是生活随笔為你收集整理的Java学习笔记-网络编程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。