Java—— TCP協議(相關代碼實現以及相關優化)

代碼運行的時候先運行服務端,然后在運行客戶端

 * TCP協議:* 1,客戶端*      創建Socket連接服務器(指定IP地址,端口號)通過IP地址找到對應的服務器*      調用Socket的getInputStream()和getOutputStream()方法獲取和服務器端相連的IO流*      輸入流可以讀取服務器端輸出流寫出的數據*      輸出流可以寫出數據到服務端的輸入流* * 2,服務端*      創建ServerSocket(需要指定端口號)*      調用ServerSocket的accept()方法接受一個客戶端請求,得到一個Socket*      調用Socket的getInputStream()和getOutputStream()方法獲取和客戶端相連的IO流*      輸入流可以讀取客戶端輸出流寫出的數據*      輸出流可以寫出數據到客戶端的輸入流
package com.wsq.tcp;
//java com.wsq.tcp.Demo1_Client
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;public class Demo1_Client {
/*** 1,客戶端*      創建Socket連接服務器(指定IP地址,端口號不超過65535)通過IP地址找到對應的服務器*      調用Socket的getInputStream()和getOutputStream()方法獲取和服務器端相連的IO流*      輸入流可以讀取服務器端輸出流寫出的數據*      輸出流可以寫出數據到服務端的輸入流* @throws IOException * @throws UnknownHostException * * * */public static void main(String[] args) throws UnknownHostException, IOException {Socket wsq = new Socket("192.168.1.182",1014);  //創建Socket集裝箱對象wsq,并且指定想要發送他人的IP,和對應的端口號,連接服務器InputStream is = wsq.getInputStream();          //獲取客戶端輸入流OutputStream os = wsq.getOutputStream();        //獲取客戶端輸入流  byte [] arr = new byte [1024];                  //創建字節數組用于讀取服務器發來的數據int len = is.read(arr);                         //讀取服務器發過來的數據System.out.println(new String (arr,0,len));     //將數據轉換成字符串打印os.write("客戶端對服務端發送請求:傻孩紙,還在睡呢?".getBytes());//客戶端向服務器寫數據wsq.close();                                    //關閉集裝箱對象wsq}
}
package com.wsq.tcp;
//java com.wsq.tcp.Demo2_Server
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;public class Demo2_Server {
/***  * 2,服務端*      創建ServerSocket(需要指定端口號)*      調用ServerSocket的accept()方法接受一個客戶端請求,得到一個Socket*      調用Socket的getInputStream()和getOutputStream()方法獲取和客戶端相連的IO流*      輸入流可以讀取客戶端輸出流寫出的數據*      輸出流可以寫出數據到客戶端的輸入流* @throws IOException * * */public static void main(String[] args) throws IOException {ServerSocket server = new ServerSocket(1014);   //創建ServerSocket并且指定端口號 Socket wsq= server.accept();                    //接收客戶端的請求,創建集裝箱對象wsq,調用accept方法來接收客戶端向服務端發出的請求InputStream is = wsq.getInputStream();          //獲取客戶端輸入流OutputStream os = wsq.getOutputStream();        //獲取客戶端輸入流  os.write("服務端響應客戶端沒,剛睡醒,不想理你".getBytes());//服務端想客戶寫出數據byte [] arr = new byte [1024];                  //創建字節數組用于接收服務器發來的數據int len = is.read(arr);                         //讀取服務器發過來的數據System.out.println(new String (arr,0,len));     //將數據轉換成字符串打印wsq.close();                                    //關閉socket集裝箱}
}
由上面的例子可以看出,該程序有點弊端,例如:讀寫的時候特別費勁,寫的時候得把字符串轉成字節數組給寫出去,讀取的時候,需要創建一個字節數組,然后才能讀進來,然后再轉換成字符串
優化:讀的時候是字符串,寫的時候也是字符串,這樣會簡便很多

優化代碼如下:

package www.wsq.TCP;
import java.io.BufferedReader;
//java com.wsq.tcp.Demo1_Client
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;public class Demo1_Client {
/*** 1,客戶端*      創建Socket連接服務器(指定IP地址,端口號不超過65535)通過IP地址找到對應的服務器*      調用Socket的getInputStream()和getOutputStream()方法獲取和服務器端相連的IO流*      輸入流可以讀取服務器端輸出流寫出的數據*      輸出流可以寫出數據到服務端的輸入流* @throws IOException * @throws UnknownHostException * * * */public static void main(String[] args) throws UnknownHostException, IOException {Socket wsq = new Socket("192.168.1.182",1014);  //創建Socket集裝箱對象wsq,并且指定想要發送他人的IP,和對應的端口號,連接服務器BufferedReader br = new BufferedReader(new InputStreamReader(wsq.getInputStream()));        //將字節流包裝成為字符流PrintStream ps = new PrintStream(wsq.getOutputStream());        //PrintStream中有寫出換行的方法  //將getInputStream()這個輸入字節流和getOutputStream()這個輸出字節流進行包裝,包裝之后,就可以直接讀一行,也可以直接寫出字符串,這樣的話,效率會更高//對于getInputStream()這個輸入字節流,輸入想整行讀,用BufferedReader,因為BufferedReader里面有ReadLine方法//對于getOutputStream()這個輸出字節流,這里不建議用BufferedWriter進行包裝,因為,BufferedWriter里面有個ReadLine方法,這個方法是以/r/n進行結束的,寫完之后還得調用newLine方法//這里建議用一個更好的流PrintStream,對getOutputStream()這個輸出字節流進行包裝,該流里面有個printLine方法,這個方法使你在寫出的時候直接加換行的,而且這個PrintLine方法也可以直接寫字符串System.out.println(br.readLine());              //讀出內容ps.println("滾,mmp");System.out.println(br.readLine());              //讀出內容ps.println("呵呵,你該唄兒厲害了~");wsq.close();                                    //關閉集裝箱對象wsq}}
有常識可知,服務端是多線程的
package www.wsq.TCP;
import java.io.BufferedReader;
//java com.wsq.tcp.Demo2_Server
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;public class Demo2_Server {
/***  * 2,服務端*      創建ServerSocket(需要指定端口號)*      調用ServerSocket的accept()方法接受一個客戶端請求,得到一個Socket*      調用Socket的getInputStream()和getOutputStream()方法獲取和客戶端相連的IO流*      輸入流可以讀取客戶端輸出流寫出的數據*      輸出流可以寫出數據到客戶端的輸入流* @throws IOException * * */public static void main(String[] args) throws IOException {demo1();ServerSocket server = new ServerSocket(1014);   //創建ServerSocket并且指定端口號 while(true){                                    //不斷地接收客戶端的請求final Socket wsq= server.accept();              //接收客戶端的請求,創建集裝箱對象wsq,調用accept方法來接收客戶端向服務端發出的請求//匿名內部類具備變量,必須被final修飾new Thread(){                                   //每接收到客戶一條請求就開啟一條線程,運用匿名內部類進行開啟線程public void run(){try {BufferedReader br = new BufferedReader(new InputStreamReader(wsq.getInputStream()));        //將字節流包裝成為字符流PrintStream ps = new PrintStream(wsq.getOutputStream());        //PrintStream中有寫出換行的方法  ps.println("歡迎來到哈哈哈哈我也不知道這是哪~~");System.out.println(br.readLine());              //readLine是以"\r\n"為結束標志的,沒有換行該行代碼就不會結束ps.println("你讓我怎樣我就怎樣,我的面子往哪放?我就不");System.out.println(br.readLine());              //讀出信息內容} catch (IOException e) {e.printStackTrace();}}}.start();wsq.close();                                    //關閉socket集裝箱}}private static void demo1() throws IOException {ServerSocket server = new ServerSocket(1014);   //創建ServerSocket并且指定端口號 Socket wsq= server.accept();                    //接收客戶端的請求,創建集裝箱對象wsq,調用accept方法來接收客戶端向服務端發出的請求BufferedReader br = new BufferedReader(new InputStreamReader(wsq.getInputStream()));        //將字節流包裝成為字符流PrintStream ps = new PrintStream(wsq.getOutputStream());        //PrintStream中有寫出換行的方法  ps.println("歡迎來到哈哈哈哈我也不知道這是哪~~");System.out.println(br.readLine());              //readLine是以"\r\n"為結束標志的,沒有換行該行代碼就不會結束ps.println("你讓我怎樣我就怎樣,我的面子往哪放?我就不");System.out.println(br.readLine());wsq.close();                                    //關閉socket集裝箱
}}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/379838.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/379838.shtml
英文地址,請注明出處:http://en.pswp.cn/news/379838.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

什么是adsense 想通過廣告掙錢的看過來

Adsense的含義Google AdSense是由Google公司推出的針對網站主(簡稱發布商)的一個互聯網廣告服務。AdSense是個合成詞。其中ad是“廣告”之意,sense是“感知”之意,綜合起來的意思就是相關廣告。Google通過程序來分析網站的內容&am…

Java GregorianCalendar getTimeZone()方法與示例

GregorianCalendar類的getTimeZone()方法 (GregorianCalendar Class getTimeZone() method) getTimeZone() method is available in java.util package. getTimeZone()方法在java.util包中可用。 getTimeZone() method is used to return the time zone for this GregorianCale…

python安全攻防---信息收集---ICMP主機探測 以及optionparser的使用

0x01 基礎概念 ICMP(Internet control Message Protocal)Internet報文協議,是TCP/IP的一種子協議,屬于網絡層協議,其目的是用于在IP主機、路由器之間傳遞控制信息 0x02 程序 程序 # -*- coding:utf-8 -*- from sca…

PHP文件系統-文件下載

一、網頁請求和響應的過程 請求: 1. HTTP 1.1 協議 版本 2. 頭信息,請求的ip,其他 3. 你請求的表單信息, 你提交給服務器的信息 http://localhost/one.php?aabbb&cccdd 響應: 1. 狀態 200 ok 404 頁面沒找到 2. 響應頭信息&a…

Java——網絡編程練習

練習一(黑馬程序員面試題):客戶端向服務器寫字符串(鍵盤錄入),服務器(多線程)將字符串反轉后寫回,客戶端再次讀取到的是反轉后的字符串 相關代碼如下: package com.wsq.test;import java.io.BufferedReader; import java.io.Buf…

第一章 基礎知識---1.4Crack小實驗--復現

0x01 程序及其編譯環境 程序如下&#xff0c;功能&#xff1a;我們必須輸入正確的密碼1234567才能得到密碼驗證的確認&#xff0c;跳出循環。否則程序提示密碼錯誤再次輸入。 #include <stdio.h>#define PASSWORD "1234567"int verify_password(char* passwo…

.net中調用exchange服務器發郵件

普通的郵件, 用System.Net.Mail 類 或 System.Web.Mail 類 處理即可, 但是Exchange Server 環境下, 這兩個類起不了作用-------至少目前我看到的情況如此. 整個過程如下: 1. 先添加COM 引用 "Microsoft CDO for Windows 2000 Library" .2. 發送郵件的代碼: CDO.Messa…

Java Double類doubleToLongBits()方法與示例

Double類doubleToLongBits()方法 (Double class doubleToLongBits() method) doubleToLongBits() method is available in java.lang package. doubleToLongBits()方法在java.lang包中可用。 doubleToLongBits() method follows IEEE 754 double floating-point standards and …

Firefox(火狐瀏覽器)彩蛋

①在地址欄上輸入&#xff1a; about:mozilla ②在地址欄上輸入&#xff1a; about:robots ③在地址欄上輸入&#xff1a; www.figma.com/404/ ④地址欄上輸入&#xff1a; chrome://global/content/alerts/alert.xul

jquery.history插件在ie中失效的問題

hash標志中不能有? ff中不存在這個問題。 轉載于:https://www.cnblogs.com/xyun/archive/2008/12/01/1345188.html

Java——反射(Class.forName()讀取配置文件舉例).

榨汁機(Juicer)榨汁機的案例&#xff1a; 分別有水果(Fruit),蘋果(Apple)&#xff0c;香蕉(Bananal)&#xff0c;橘子(Orange),榨汁(squeeze) 要求&#xff1a; 榨出不同的水果汁來喝 //一般方法求解 package com.testl;public class Text1 {public static void main(Strin…

java 根據類名示例化類_Java類類getEnclosingClass()方法及示例

java 根據類名示例化類類的類getEnclosingClass()方法 (Class class getEnclosingClass() method) getEnclosingClass() method is available in java.lang package. getEnclosingClass()方法在java.lang包中可用。 getEnclosingClass() method is used to return recent or im…

C++:cin.getline

轉&#xff1a;百度百科 http://baike.baidu.com/view/2383876.htm cin.getline 此函數是按行讀取,其語法為:cin.getline(字符指針,字符個數N,結束符); 功能是&#xff1a;一次讀取多個字符(包括空白字符&#xff09;&#xff0c;直到讀滿N-1個&#xff0c;或者遇到指定的結束符…

端口復用和重映射--STM32F103

什么是端口復用&#xff1f; STM32中有很多內置外設&#xff0c;這些外設的引腳都是與GPIO復用的&#xff0c;什么時候復用呢&#xff1f;就是當一個GPIO作為內置外設引腳使用時&#xff0c;就叫做復用。比如串口1的發送接收引腳是PA9&#xff0c;PA10&#xff0c;當PA9&#…

考研數學

眼前儼然一副冬的氣象&#xff0c;伴隨氣溫的驟降&#xff0c;考研復習也進入異常緊張的階段。在考試前這兩個月里&#xff0c;考生如何復習數學&#xff0c;成績還可以有所提高。萬學?海文數學教研組針對沖刺階段數學復習歸納總結以下復習經驗和建議&#xff0c;供大家參考。…

一個很好的自學網站~推薦一下

http://www.51zxw.net/study.asp?vip15746908

[轉]Ubuntu遠程桌面登陸

原文地址&#xff1a;http://www.cnblogs.com/xdzone/archive/2011/03/10/1979644.html 1.xp下默認的遠程桌面協議是rdp&#xff0c;默認端口3389&#xff0c;而ubuntu用的時vnc&#xff1a;默認端口5900 2.首先被訪問的主機&#xff08;windows/linux&#xff09;都要設置為允…

NVIC中斷管理---STM32

NVIC&#xff1a;嵌套向量中斷控制器 在了解中斷之前&#xff0c;我們先了解搶占優先級和響應優先級 搶占優先級和響應優先級 搶占優先級決定能不能打斷&#xff0c;高優先級的搶占可以中斷低優先級的搶占響應優先級在搶占優先級相同時&#xff0c;高響應優先級先執行&#x…

Java BigDecimal stripTrailingZeros()方法與示例

BigDecimal類stripTrailingZeros()方法 (BigDecimal Class stripTrailingZeros() method) stripTrailingZeros() method is available in java.math package. stripTrailingZeros()方法在java.math包中可用。 stripTrailingZeros() method is used to get a BigDecimal that is…

外部中斷---STM32F1

外部中斷概述 STM32的中斷控制器支持19個外部中斷/事件請求&#xff1a; 線0-15&#xff1a;對應外部IO口的輸入中斷線16&#xff1a;連接到PVD輸出線17&#xff1a;連接到RTC鬧鐘事件線18&#xff1a;連接到USB喚醒事件 STM32每個IO口都有可以作為外部中斷輸入&#xff0c;…