java网络编程(六)
戳上面的藍(lán)字關(guān)注我們哦!
?精彩內(nèi)容?
?
精選java等全套視頻教程
精選java電子圖書
大數(shù)據(jù)視頻教程精選
java項(xiàng)目練習(xí)精選
網(wǎng)絡(luò)編程示例
“實(shí)踐出真知”,所以在進(jìn)行技術(shù)學(xué)習(xí)時(shí),還是需要進(jìn)行很多的練習(xí),才可以體會(huì)技術(shù)的奧妙,下面通過兩個(gè)簡單的示例,演示網(wǎng)絡(luò)編程的實(shí)際使用。
1.3.1質(zhì)數(shù)判別示例
該示例實(shí)現(xiàn)的功能是質(zhì)數(shù)判斷,程序?qū)崿F(xiàn)的功能為客戶端程序接收用戶輸入的數(shù)字,然后將用戶輸入的內(nèi)容發(fā)送給服務(wù)器端,服務(wù)器端判斷客戶端發(fā)送的數(shù)字是否是質(zhì)數(shù),并將判斷的結(jié)果反饋給客戶端,客戶端根據(jù)服務(wù)器端的反饋顯示判斷結(jié)果。
質(zhì)數(shù)的規(guī)則是:最小的質(zhì)數(shù)是2,只能被1和自身整除的自然數(shù)。當(dāng)用戶輸入小于2的數(shù)字,以及輸入的內(nèi)容不是自然數(shù)時(shí),都屬于非法輸入。
網(wǎng)絡(luò)程序的功能都分為客戶端程序和服務(wù)器端程序?qū)崿F(xiàn),下面先描述一下每個(gè)程序分別實(shí)現(xiàn)的功能:
1、 客戶端程序功能:
接收用戶控制臺(tái)輸入
判斷輸入內(nèi)容是否合法
按照協(xié)議格式生成發(fā)送數(shù)據(jù)
發(fā)送數(shù)據(jù)
接收服務(wù)器端反饋
解析服務(wù)器端反饋信息,并輸出
2、 服務(wù)器端程序功能:
接收客戶端發(fā)送數(shù)據(jù)
按照協(xié)議格式解析數(shù)據(jù)
判斷數(shù)字是否是質(zhì)數(shù)
根據(jù)判斷結(jié)果,生成協(xié)議數(shù)據(jù)
將數(shù)據(jù)反饋給客戶端
分解好了網(wǎng)絡(luò)程序的功能以后,就可以設(shè)計(jì)網(wǎng)絡(luò)協(xié)議格式了,如果該程序的功能比較簡單,所以設(shè)計(jì)出的協(xié)議格式也不復(fù)雜。
客戶端發(fā)送協(xié)議格式:
將用戶輸入的數(shù)字轉(zhuǎn)換為字符串,再將字符串轉(zhuǎn)換為byte數(shù)組即可。
例如用戶輸入16,則轉(zhuǎn)換為字符串“16”,使用getBytes轉(zhuǎn)換為byte數(shù)組。
客戶端發(fā)送“quit”字符串代表結(jié)束連接
服務(wù)器端發(fā)送協(xié)議格式:
反饋數(shù)據(jù)長度為1個(gè)字節(jié)。數(shù)字0代表是質(zhì)數(shù),1代表不是質(zhì)數(shù),2代表協(xié)議格式錯(cuò)誤。
例如客戶端發(fā)送數(shù)字12,則反饋1,發(fā)送13則反饋0,發(fā)送0則反饋2。
功能設(shè)計(jì)完成以后,就可以分別進(jìn)行客戶端和服務(wù)器端程序的編寫了,在編寫完成以后聯(lián)合起來進(jìn)行調(diào)試即可。
下面分別以TCP方式和UDP方式實(shí)現(xiàn)該程序,注意其實(shí)現(xiàn)上的差異。不管使用哪種方式實(shí)現(xiàn),客戶端都可以多次輸入數(shù)據(jù)進(jìn)行判斷。對(duì)于UDP方式來說,不需要向服務(wù)器端發(fā)送quit字符串。
以TCP方式實(shí)現(xiàn)的客戶端程序代碼如下:
package example1; import java.io.*; import java.net.*; /*** 以TCP方式實(shí)現(xiàn)的質(zhì)數(shù)判斷客戶端程序*/ public class TCPPrimeClient {static BufferedReader br;static Socket socket;static InputStream is;static OutputStream os;/**服務(wù)器IP*/final static String HOST = "127.0.0.1";/**服務(wù)器端端口*/final static int PORT = 10005;public static void main(String[] args) {init(); //初始化while(true){System.out.println("請(qǐng)輸入數(shù)字:");String input = readInput(); //讀取輸入if(isQuit(input)){ //判讀是否結(jié)束byte[] b = "quit".getBytes();send(b);break; //結(jié)束程序}if(checkInput(input)){ //校驗(yàn)合法//發(fā)送數(shù)據(jù)send(input.getBytes());//接收數(shù)據(jù)byte[] data = receive();//解析反饋數(shù)據(jù)parse(data);}else{System.out.println("輸入不合法,請(qǐng)重新輸入!");}}close(); //關(guān)閉流和連接}/*** 初始化*/private static void init(){try {br = new BufferedReader(new InputStreamReader(System.in));socket = new Socket(HOST,PORT);is = socket.getInputStream();os = socket.getOutputStream();} catch (Exception e) {}}/*** 讀取客戶端輸入*/private static String readInput(){try {return br.readLine();} catch (Exception e) {return null;}}/*** 判斷是否輸入quit* @param input 輸入內(nèi)容* @return true代表結(jié)束,false代表不結(jié)束*/private static boolean isQuit(String input){if(input == null){return false;}else{if("quit".equalsIgnoreCase(input)){return true;}else{return false;}}}/*** 校驗(yàn)輸入* @param input 用戶輸入內(nèi)容* @return true代表輸入符合要求,false代表不符合*/private static boolean checkInput(String input){if(input == null){return false;}try{int n = Integer.parseInt(input);if(n >= 2){return true;}else{return false;}}catch(Exception e){return false; //輸入不是整數(shù)}}/*** 向服務(wù)器端發(fā)送數(shù)據(jù)* @param data 數(shù)據(jù)內(nèi)容*/private static void send(byte[] data){try{os.write(data);}catch(Exception e){}}/*** 接收服務(wù)器端反饋* @return 反饋數(shù)據(jù)*/private static byte[] receive(){byte[] b = new byte[1024];try {int n = is.read(b);byte[] data = new byte[n];//復(fù)制有效數(shù)據(jù)System.arraycopy(b, 0, data, 0, n);return data;} catch (Exception e){}return null;}/*** 解析協(xié)議數(shù)據(jù)* @param data 協(xié)議數(shù)據(jù)*/private static void parse(byte[] data){if(data == null){System.out.println("服務(wù)器端反饋數(shù)據(jù)不正確!");return;}byte value = data[0]; //取第一個(gè)byte//按照協(xié)議格式解析switch(value){case 0:System.out.println("質(zhì)數(shù)");break;case 1:System.out.println("不是質(zhì)數(shù)");break;case 2:System.out.println("協(xié)議格式錯(cuò)誤");break;}}/*** 關(guān)閉流和連接*/private static void close(){try{br.close();is.close();os.close();socket.close();}catch(Exception e){e.printStackTrace();}} }在該代碼中,將程序的功能使用方法進(jìn)行組織,使得結(jié)構(gòu)比較清晰,核心的邏輯流程在main方法中實(shí)現(xiàn)。
以TCP方式實(shí)現(xiàn)的服務(wù)器端的代碼如下:
package example1; import java.net.*; /*** 以TCP方式實(shí)現(xiàn)的質(zhì)數(shù)判別服務(wù)器端*/ public class TCPPrimeServer {public static void main(String[] args) {final int PORT = 10005;ServerSocket ss = null;try {ss = new ServerSocket(PORT);System.out.println("服務(wù)器端已啟動(dòng):");while(true){Socket s = ss.accept();new PrimeLogicThread(s);}} catch (Exception e) {}finally{try {ss.close();} catch (Exception e2) {}}} } package example1; import java.io.*; import java.net.*; /*** 實(shí)現(xiàn)質(zhì)數(shù)判別邏輯的線程*/ public class PrimeLogicThread extends Thread {Socket socket;InputStream is;OutputStream os;public PrimeLogicThread(Socket socket){this.socket = socket;init();start();}/*** 初始化*/private void init(){try{is = socket.getInputStream();os = socket.getOutputStream();}catch(Exception e){}}public void run(){while(true){//接收客戶端反饋byte[] data = receive();//判斷是否是退出if(isQuit(data)){break; //結(jié)束循環(huán)}//邏輯處理byte[] b = logic(data);//反饋數(shù)據(jù)send(b);}close();}/*** 接收客戶端數(shù)據(jù)* @return 客戶端發(fā)送的數(shù)據(jù)*/private byte[] receive(){byte[] b = new byte[1024];try {int n = is.read(b);byte[] data = new byte[n];//復(fù)制有效數(shù)據(jù)System.arraycopy(b, 0, data, 0, n);return data;} catch (Exception e){}return null;}/*** 向客戶端發(fā)送數(shù)據(jù)* @param data 數(shù)據(jù)內(nèi)容*/private void send(byte[] data){try{os.write(data);}catch(Exception e){}}/*** 判斷是否是quit* @return 是返回true,否則返回false*/private boolean isQuit(byte[] data){if(data == null){return false;}else{String s = new String(data);if(s.equalsIgnoreCase("quit")){return true;}else{return false;}}}private byte[] logic(byte[] data){//反饋數(shù)組byte[] b = new byte[1];//校驗(yàn)參數(shù)if(data == null){b[0] = 2;return b;}try{//轉(zhuǎn)換為數(shù)字String s = new String(data);int n = Integer.parseInt(s);//判斷是否是質(zhì)數(shù)if(n >= 2){boolean flag = isPrime(n);if(flag){b[0] = 0;}else{b[0] = 1;}}else{b[0] = 2; //格式錯(cuò)誤System.out.println(n);}}catch(Exception e){e.printStackTrace();b[0] = 2;}return b;}/**** @param n* @return*/private boolean isPrime(int n){boolean b = true;for(int i = 2;i <= Math.sqrt(n);i++){if(n % i == 0){b = false;break;}}return b;}/*** 關(guān)閉連接*/private void close(){try {is.close();os.close();socket.close();} catch (Exception e){}} }本示例使用的服務(wù)器端的結(jié)構(gòu)和前面示例中的結(jié)構(gòu)一致,只是邏輯線程的實(shí)現(xiàn)相對(duì)來說要復(fù)雜一些,在線程類中的logic方法中實(shí)現(xiàn)了服務(wù)器端邏輯,根據(jù)客戶端發(fā)送過來的數(shù)據(jù),判斷是否是質(zhì)數(shù),然后根據(jù)判斷結(jié)果按照協(xié)議格式要求,生成客戶端反饋數(shù)據(jù),實(shí)現(xiàn)服務(wù)器端要求的功能。
回復(fù)以下關(guān)鍵字獲取更多學(xué)習(xí)資源
java基礎(chǔ)|html5|css|js|jquery|angularJs|ajax|node.js|javaEE基礎(chǔ)| |struts2|hibernate|spring|svn|maven|springmvc|mybatis|linux|oracle| |luncene|solr|redis|springboot|架構(gòu)師資源|dubbo|php|webservice|c++基礎(chǔ)|nginx|mysql|sqlserver|asp.net
更多學(xué)習(xí)資源逐步更新,請(qǐng)置頂公眾號(hào)不要錯(cuò)過更新
好好學(xué)java
每日推送java優(yōu)質(zhì)文章、視頻教程、熱點(diǎn)資訊
微信ID:SIHAI0911
長按左側(cè)二維碼關(guān)注
總結(jié)
以上是生活随笔為你收集整理的java网络编程(六)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java面试题大合集(开发者必看三)
- 下一篇: java网络编程(七)