Java Socket編程實(shí)現(xiàn)簡單的問候服務(wù)
本文實(shí)例講解了Java Socket編程實(shí)現(xiàn)簡單的問候服務(wù)的詳細(xì)代碼,供大家參考,具體內(nèi)容如下
服務(wù)器端:
實(shí)現(xiàn)一個(gè)最簡單的Hello服務(wù),打印輸出客戶端IP地址到控制臺,對任何連接的客戶端都會發(fā)送一串字符(Hello, Java Socket)然后關(guān)閉與客戶端連接。等待下一個(gè)客戶端的連接請求到來。
客戶端:
實(shí)現(xiàn)一個(gè)最簡單的Socket連接到Hello服務(wù)器端,接受服務(wù)器端發(fā)送過來的字節(jié)數(shù)據(jù)打印并輸出內(nèi)容到控制臺。
關(guān)鍵技巧:
由于JAVA中提供非常多的輸入與輸出流API,導(dǎo)致很多初學(xué)者接觸JAVA SOCKET編程時(shí),由于對網(wǎng)絡(luò)字節(jié)通信的本質(zhì)缺乏了解,直接一個(gè)readline()去接受Socket字節(jié)流。但是由于發(fā)送一方并沒有發(fā)送/r/n導(dǎo)致一直無法讀到數(shù)據(jù),這個(gè)是最常見的一個(gè)錯誤。另外一些常見的錯誤包括沒有初始化接受緩沖區(qū)導(dǎo)致字符亂碼,沒有按照讀入接受到字節(jié)數(shù)重新組裝,導(dǎo)致接受到的數(shù)據(jù)異常。所以代碼演示了什么叫按字節(jié)發(fā)送與按字節(jié)接受,這個(gè)是網(wǎng)絡(luò)編程中非常重要的概念與原則。讓那些輸入流println()方法與輸出流readline()方法見鬼去吧,不是不好用,而是我建議你不要用,因?yàn)槟切恋K你的網(wǎng)絡(luò)編程本質(zhì)的認(rèn)識與理解。另外我要特別說明一下:有時(shí)候flush()真的不是必須的除非你使用了帶有緩沖的輸入與輸出流來讀寫字節(jié)。
服務(wù)器端代碼:
package com.gloomyfish.socket.tutorial.two; import java.io.DataOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public class HelloService extends Thread { private ServerSocket serverSocket; public HelloService(int port) throws IOException { serverSocket = new ServerSocket(port); } public void run() { try { while(true) { System.out.println("Waiting for client on port " + serverSocket.getLocalPort()); Socket client = serverSocket.accept(); // blocked & waiting for income socket System.out.println("Just connected to " + client.getRemoteSocketAddress()); DataOutputStream dos = new DataOutputStream(client.getOutputStream()); byte[] hello = "Hello, Java Socket".getBytes(); dos.write(hello, 0, hello.length); dos.close(); client.close(); } } catch(Exception e) { e.printStackTrace(); } } public static void main(String[] args) { try { HelloService service = new HelloService(9999); service.start(); } catch (IOException e) { e.printStackTrace(); } } }
服務(wù)器在端口9999監(jiān)聽并等待連接,使用Java Thread來實(shí)現(xiàn)服務(wù)器端啟動。
客戶端代碼如下:
package com.gloomyfish.socket.tutorial.two; import java.io.DataInputStream; import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; public class HelloClient { private int clientNumber; private SocketAddress address; public HelloClient(int clientNum) { clientNumber = clientNum; } public void setupClients(String serverHostName, int port) throws IOException { address = new InetSocketAddress(serverHostName, port); for(int i=0; i<clientNumber; i++) { System.out.println(); System.out.println("start client No. " + (i+1)); Socket socket = new Socket(); socket.connect(address); DataInputStream bufferedReader = new DataInputStream(socket.getInputStream()); byte[] cbuff = new byte[256]; char[] charBuff = new char[256]; int size = 0; while( (size = bufferedReader.read(cbuff))> 0) { convertByteToChar(cbuff, charBuff, size); System.out.println(charBuff); } bufferedReader.close(); socket.close(); } } private void convertByteToChar(byte[] cbuff, char[] charBuff, int size) { for(int i=0; i<charBuff.length; i++) { if(i < size) { charBuff[i] = (char)cbuff[i]; } else { charBuff[i] = ' '; } } } public static void main(String[] args) { try { HelloClient client = new HelloClient(10); client.setupClients("localhost", 9999); } catch (IOException e) { e.printStackTrace(); } } }
啟動10個(gè)客戶端去連接服務(wù)器端,接受到服務(wù)器端問候以后客戶端關(guān)閉連接。
特別提示:一定要初始化緩沖區(qū)charBuff
程序運(yùn)行結(jié)果:
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助。
- Java字符流與字節(jié)流區(qū)別與用法分析
- 詳解Java中字符流與字節(jié)流的區(qū)別
- Java編程中字節(jié)流與字符流IO操作示例
- 深入解析Java編程中面向字節(jié)流的一些應(yīng)用
- java基于Socket做一個(gè)簡單下載器
- java使用Socket實(shí)現(xiàn)SMTP協(xié)議發(fā)送郵件
- java Socket實(shí)現(xiàn)網(wǎng)頁版在線聊天
- java實(shí)現(xiàn)一個(gè)簡單TCPSocket聊天室功能分享
- Java基于Socket實(shí)現(xiàn)HTTP下載客戶端
- Java socket字節(jié)流傳輸示例解析
相關(guān)文章
Java獲取漢字拼音的全拼和首拼實(shí)現(xiàn)代碼分享
這篇文章主要介紹了Java獲取漢字拼音的全拼和首拼實(shí)現(xiàn)代碼分享,本文直接給出實(shí)現(xiàn)代碼,需要的朋友可以參考下2015-06-06springboot使用redis對單個(gè)對象進(jìn)行自動緩存更新刪除的實(shí)現(xiàn)
本文主要介紹了springboot使用redis對單個(gè)對象進(jìn)行自動緩存更新刪除的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08Java網(wǎng)絡(luò)通信中ServerSocket的設(shè)計(jì)優(yōu)化方案
今天小編就為大家分享一篇關(guān)于Java網(wǎng)絡(luò)通信中ServerSocket的設(shè)計(jì)優(yōu)化方案,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-04-04Spring如何基于xml實(shí)現(xiàn)聲明式事務(wù)控制
這篇文章主要介紹了Spring如何基于xml實(shí)現(xiàn)聲明式事務(wù)控制,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10詳解Spring Security的Web應(yīng)用和指紋登錄實(shí)踐
這篇文章主要介紹了詳解Spring Security的Web應(yīng)用和指紋登錄實(shí)踐,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-03-03SpringMvc向request域中設(shè)置數(shù)據(jù)的方法
這篇文章主要介紹了SpringMvc向request域中設(shè)置數(shù)據(jù)的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-09-09