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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

黑马程序员 java基础之网络编程TCP

發布時間:2023/12/9 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 黑马程序员 java基础之网络编程TCP 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


TCP網絡傳輸。

客戶端和服務端

?

分別對應著兩個對象。

Scoket(客戶端)和ServerSocket(服務端)。

?

? Socket(String ?address, int port)

????????? 創建一個流套接字并將其連接到指定 IP 地址的指定端口號。

這個客戶端在一建立的情況下就去連接服務端。

通過指定地址和指定的端口找到服務端。并與之建立連接。

?

步驟:
1.創建Socket服務,并指定要連接的主機和端口。

?? Socket s = new Socket("localhost",10002);

?? 如果上述這步成功了的話。也就是通路建立了。

當通路一建立,就有一個Socket流,也就是網絡流。

兩端之間建立了一個網絡流。Socket中既有輸入流也有輸出流,

一旦建立連接,在Socket中就可以取到輸入流和輸出流對數據進行操作。

?

流不用去建立,只要通路一建立,流就存在了。

?

getOutputStream()

?????????返回此套接字的輸出流。

getInputStream()

?????????返回此套接字的輸入流。

?

服務端

?

服務端沒有自己的流對象。

服務端和客戶端連接的時候,就使用了客戶端的流對象和客戶端進行操作。

?

public classTCPSocket {

?

????? /**

????? ?*@param args

????? ?*/

????? public static void main(String[] args)throws Exception

????? {

??????????

?????????? Socket s = newSocket("localhost",10002);

?????????? //為了發送數據,應該獲取socket流中的輸出流

?????????? OutputStream os =s.getOutputStream();

??????????

?????????? BufferedWriter bw = newBufferedWriter(new OutputStreamWriter(os));

?

?????????? bw.write("tcp,gemenwolaile");

?????????? bw.flush();

?????????? //而在這里不同去關流

?????????? s.close();

??????????

????? }

?

}

?

/*

?* 需求:定義端點接收數據并打印在控制臺上。

?* 服務端:

?* 1.建立服務端的Socket服務。通過ServerSocket類去建立。

?* 一旦建立,并監聽一個端口。

?* 2.獲取鏈接過來的客戶端對象。

?*?? 通過ServerSocket的accept方法去獲得。所以這個方法是阻塞式。

?* 3.客戶端如果發過來數據,那么服務端要使用對應的客戶端對象,并獲取到該客戶端

?* 的讀取流來讀取發過來的數據。并打印在控制臺。

?* 4.關閉服務端。(可選)

?*?

?* */

class TcpServer

{

????? public static void main(String[] args)throws Exception

????? {

??????????

?????????? //建立服務端Socket服務,并監聽一個端口。

?????????? ServerSocket ss? = new ServerSocket(10002);

?????????? //通過accept方法獲取連接過來的客戶端對象。

?????????? Socket s = ss.accept();

??????????

?????????? System.out.println(s.getInetAddress().getHostAddress());

?????????? //獲取客戶端發送過來的數據,那么要使用客戶端對象的讀取流方法來讀取數據。

??????????

?????????? InputStream in = s.getInputStream();

??????????

?????????? byte[] buf = new byte[1024];

??????????

?????????? int len = in.read(buf);

??????????

?????????? System.out.println(newString(buf,0,len));

??????????

?????

?????????? s.close();//關閉客戶端。

??????????

??????????

??????????

????? }

?????

?

}

?

必須先啟動服務端。

?

?

?

演示tcp傳輸的客戶端和服務端的互訪。

需求:客戶端給服務端發送數據,服務端收到后,給客戶端反饋信息。

?

/*

?1.建立socket服務。指定要連接的主機和端口

?2.獲取socket流中的輸出流,將數據寫到該流中。通過網絡發送給服務端。

?3.獲取socket流中的輸入流,將服務器反饋的數據獲取到,并打印。

?4.關閉客戶端資源。

?*/

?

class TcpClient2

{

????? public static void main(String[] args)throws Exception

????? {

?????????? Socket s =? new Socket("localhost",10004);

?????????? OutputStream os = s.getOutputStream();

?????????? os.write("nihao".getBytes());

??????????

?????????? InputStream is = s.getInputStream();

??????????

?????????? byte [] arr = new byte[1024];

?????????? //十分要主要,這里的read讀的是Socket流。也是一個阻塞式方法。只有服務端往回發送數據的時候,才會解除阻塞。

?????????? int len = is.read(arr);

??????????

?????????? System.out.println(newString(arr,0,len));

?????????? s.close();

?????

??????????

????? }

}

class TcpServer2

{

????? public static void main(String[] args)throws Exception

????? {

?????????? ServerSocket ss = newServerSocket(10004);

??????????

?????????? Socket s = ss.accept();

?????????? InputStream is = s.getInputStream();

??????????

?????????? byte [] arr = new byte[1024];

?????????? int len = is.read(arr);

??????????

?????????? System.out.println(newString(arr,0,len));

??????????

?????????? OutputStream os =s.getOutputStream();

?????????? os.write("完成".getBytes());

??????????

?????????? s.close();

??????????

??????????

??????????

??????????

????? }

}

?

?

?

?

package day5;

importjava.net.*;

importjava.io.*;

public classTCPSocket2 {

?

?????

????? public static void main(String[] args) {

?????????? // TODO Auto-generated method stub

?

????? }

?

}

?

?

class Client3

{

?

????? public static void main(String[] args)throws Exception

????? {

?????????? Socket s = newSocket("localhost",10009);

??????????

?????????? BufferedWriter bw = new BufferedWriter(newOutputStreamWriter(s.getOutputStream()));

??????????

?????????? BufferedReader br = newBufferedReader(new InputStreamReader(System.in));

?????????? String ss = null;

??????????

?????????? BufferedReader brr = newBufferedReader(new InputStreamReader(s.getInputStream()));

?????????? while((ss = br.readLine())!=null)

?????????? {

???????????????? bw.write(ss);

???????????????? bw.newLine();

???????????????? bw.flush();

????????????????

?????????? System.out.println(brr.readLine());

?????

?????????? }

??????????

??????????

?????????? br.close();

?????????? s.close();

??????????

????????????????

??????????

????? }

}

class Server3

{

?

????? public static void main(String[] args)throws Exception

????? {

?????????? ServerSocket ss = newServerSocket(10009);

??????????

?????????? Socket s = ss.accept();

?????????? InputStream is = s.getInputStream();

??????????

?????????? BufferedReader br = newBufferedReader(new InputStreamReader(is));

??????????

?????????? OutputStream os =s.getOutputStream();

?????????? BufferedWriter bw = new BufferedWriter(newOutputStreamWriter(os));

?????????? String sss? = null;

?????????? while((sss = br.readLine())!=null)

?????????? {

???????????????? //上邊的readLine只有在看到回車符后才能結束,也就是解除阻塞。

??????????

????????????????

??????????

?????????? bw.write(sss.toUpperCase());

?????????? bw.newLine();

?????????? bw.flush();

?????????? }

??????????

?????????? //有一個疑問,為什么當客戶端結束的時候,服務端也結束了,

?????????? //這是因為,當客戶端調用s.close()時,會在流里寫一個-1,

?????????? //然后服務器端就跳出循環,然后通過ss關閉服務器。

?????????? ss.close();

??????????

??????????

??????????

??????????

????? }

}

?

要注意,對于讀取流中的阻塞式方法來說,一定要將發送發的緩沖區刷新。

而且必須將行結束符寫到這個流中。

?

對于服務器端的阻塞式方法,如readLine(),必須在客戶端發送一個標志,讓服務器端知道其結束了,否則服務器一直處于讀取數據的狀態。

在客戶端使用

s.shutdownOutput();//關閉客戶端的輸出流,相當于給流中加入一個結束標記

?

?

下邊,我們使用更高級的協議去完成一個自定義瀏覽器和tomcat服務器的處理請求。

可以直接使用應用層的協議去封裝。

URL url = newURL("http://localhost:8080/GP2/index.jsp");

//首先將url地址封裝到一個對象為URL中。

URLConnectionconn = url.openConnection();

//這個URLConnection就封裝了有關底層協議的一些信息。

//也就通過一些應用層的協議進行拆包,并將這些屬性封裝到這個對象中去.

//然后通過openConnection()在內部幫助我們去完成Socket等一系列連接動作。

//所以不同寫Socket(是在傳輸層上的協議),而且是帶著協議去封裝的。

?

?

//當連接成功,當然可以將其服務端傳遞過來的數據拿到。也就是得到輸入流對象。

從獲取值

InputStream is =conn.getInputStream();

?

//從而從這個流對象中的得到值

byte [] arr =new byte[1024];

??????????

?????????? int len = 0;

?????????? while((len = is.read(arr))!=-1)

?????????? {

???????????????? System.out.println(newString(arr,0,len));

????????????????

?????????? }

?

這時候傳遞過來的數據就沒有了響應頭。而直接打出html中的信息。

這是因為。當底層的網絡協議把數據封裝好之后(包括響應頭),通過應用層去拆包之后,將數據和響應頭分離開來,得到的數據就只剩數據了。

而這些響應頭中的信息,可以通過URLConnection對象中的一系列方法進行簡析.

比如說:System.out.println(conn.getHeaderField("Server"));

可以得到有關服務器的信息。

當瀏覽器寫入一個網址之后,去訪問某一臺主機的時候.它到底做什么了事情?

?在上網的時候,先去本地找hosts中的各自域名的映射關系.

當本地有,就返回本地的,如localhost,如果本地沒有,就去各自運營商提供的域名服務器DNS中去尋找映射關系,最后使用ip地址找到對應的服務器,使用端口找到對應的應用程序.如果直接輸入ip地址,則不走域名簡析.

?

?

?

轉載于:https://www.cnblogs.com/xiewen3410/archive/2013/05/14/3078647.html

總結

以上是生活随笔為你收集整理的黑马程序员 java基础之网络编程TCP的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。