java實現Socket通信之單線程服務
前言
使用基于TCP 協議的雙向通信時,網絡中的兩個應用程序之間必須首先建立一個連接,這兩個程序通過一個雙向的通信連接實現數據的交換,這個連接的一端稱為一個socket。
建立網絡通信連接至少要一對端口號(socket)。socket本質是編程接口(API),對TCP/IP的封裝,TCP/IP也要提供可供程序員做網絡開發(fā)所用的接口,這就是Socket編程接口;HTTP是轎車,提供了封裝或者顯示數據的具體形式;Socket是發(fā)動機,提供了網絡通信的能力。
Socket的英文原義是“孔”或“插座”。作為BSD UNIX的進程通信機制,取后一種意思。通常也稱作"套接字",用于描述IP地址和端口,是一個通信鏈的句柄,可以用來實現不同虛擬機或不同計算機之間的通信。在Internet上的主機一般運行了多個服務軟件,同時提供幾種服務。每種服務都打開一個Socket,并綁定到一個端口上,不同的端口對應于不同的服務。Socket正如其英文原意那樣,像一個多孔插座。一臺主機猶如布滿各種插座的房間,每個插座有一個編號,有的插座提供220伏交流電, 有的提供110伏交流電,有的則提供有線電視節(jié)目。 客戶軟件將插頭插到不同編號的插座,就可以得到不同的服務。
使用 socket 的通信模式
java.net 程序包將基于TCP 通信的socket 封裝為兩個類:類Socket 表達了一個用于建立TCP 連接的socket,該socket 既可由客戶程序使用,也可由服務程序
使用;類ServerSocket 則是一個服務端專門監(jiān)聽客戶程序連接請求的socket 的抽象,僅在服務程序中使用。
Socket通信過程

服務器端:
① 創(chuàng)建ServerSocket對象,綁定監(jiān)聽端口
② 通過accept()方法監(jiān)聽客戶端請求
③ 連接建立后,通過輸入流讀取客戶端發(fā)送的請求信息
④ 通過輸出流向客戶端發(fā)送響應信息
⑤ 關閉連接
客戶端:
① 創(chuàng)建Socket對象,指明需要連接的服務器的地址和端口號
② 連接建立后,通過輸出流想服務器端發(fā)送請求信息
③ 通過輸入流獲取服務器響應的信息
④ 關閉連接
單線程服務程序代碼
服務端:
import java.net.*;
import java.io.*;
public class EchoServer {
public static void main(String[] args)throws IOException {
if (args.length != 1) {
System.out.println("用法:EchoServer <端口號>");
return ;
}
// 監(jiān)聽客戶程序的連接請求
ServerSocket listenSocket = new ServerSocket(Integer.parseInt(args[0]));
System.out.println("服務程序正在監(jiān)聽端口" + args[0]);
Socket socket = listenSocket.accept();
// 從與客戶程序的新建連接獲取輸入流和輸出流
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader
(socket.getInputStream()));
// 從客戶端讀取數據,并寫回數據的加工結果
String message;
while ((message = in.readLine()) != null) {
System.out.println("收到請求:" + message);
out.println(message.toUpperCase());
}
// 關閉連接
out.close();
in.close();
socket.close();
listenSocket.close();
}
}
客戶端:
import java.net.*;
import java.io.*;
public class EchoClient {
public static void main(String[] args)throws Exception {
if (args.length != 2) {
System.out.println("用法:EchoClient <主機名> <端口號>");
return ;
}
// 建立連接并打開相關聯的輸入流和輸出流
Socket socket = new Socket(args[0], Integer.parseInt(args[1]));
System.out.println("當前socket信息:" + socket);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader
(socket.getInputStream()));
// 將控制臺輸入的字符串發(fā)送給服務端,并顯示從服務端獲取的處理結果
BufferedReader stdIn = new BufferedReader(new InputStreamReader
(System.in));
String userInput;
while ((userInput = stdIn.readLine()) != null) {
out.println(userInput);
System.out.println("返回:" + in.readLine());
}
stdIn.close();
// 關閉連接
out.close();
in.close();
socket.close();
}
}
運行結果示例(基于windows)

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
java如何自定義List中的sort()排序,用于日期排序
這篇文章主要介紹了java如何自定義List中的sort()排序,用于日期排序,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11
JDK14的新特性NullPointerExceptions的使用
這篇文章主要介紹了JDK14的新特性NullPointerExceptions的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-04-04
Java Hutool工具實現驗證碼生成及Excel文件的導入和導出
Hutool是一個小而全的Java工具類庫,通過靜態(tài)方法封裝,降低相關API的學習成本,提高工作效率,本文主要介紹了使用Hutool工具實現驗證碼生成和excel文件的導入、導出,需要的朋友可參考一下2021-11-11
windows 32位eclipse遠程hadoop開發(fā)環(huán)境搭建
這篇文章主要介紹了windows 32位eclipse遠程hadoop開發(fā)環(huán)境搭建的相關資料,需要的朋友可以參考下2016-07-07

