c++ socket线程池_java 网络编程,Socket编程
Java的網(wǎng)絡(luò)編程主要涉及到的內(nèi)容是Socket編程,那么什么是Socket呢?簡(jiǎn)單地說,Socket,套接字,就是兩臺(tái)主機(jī)之間邏輯連接的端點(diǎn)。TPC/IP協(xié)議是傳輸層協(xié)議,主要解決數(shù)據(jù)如何在網(wǎng)絡(luò)中傳輸,而HTTP是應(yīng)用層協(xié)議,主要解決如何包裝數(shù)據(jù)。Socket,本質(zhì)上就是一組接口,是對(duì)TCP/IP協(xié)議的封裝和應(yīng)用(程序員層面上)。
套接字使用TCP提供了兩臺(tái)計(jì)算機(jī)之間的通信機(jī)制。 客戶端程序創(chuàng)建一個(gè)套接字,并嘗試連接服務(wù)器的套接字。
當(dāng)連接建立時(shí),服務(wù)器會(huì)創(chuàng)建一個(gè) Socket 對(duì)象。客戶端和服務(wù)器現(xiàn)在可以通過對(duì) Socket 對(duì)象的寫入和讀取來進(jìn)行通信。
java.net.Socket 類代表一個(gè)套接字,并且 java.net.ServerSocket 類為服務(wù)器程序提供了一種來監(jiān)聽客戶端,并與他們建立連接的機(jī)制。
以下步驟在兩臺(tái)計(jì)算機(jī)之間使用套接字建立TCP連接時(shí)會(huì)出現(xiàn):
服務(wù)器實(shí)例化一個(gè) ServerSocket 對(duì)象,表示通過服務(wù)器上的端口通信。
服務(wù)器調(diào)用 ServerSocket 類的 accept() 方法,該方法將一直等待,直到客戶端連接到服務(wù)器上給定的端口。
服務(wù)器正在等待時(shí),一個(gè)客戶端實(shí)例化一個(gè) Socket 對(duì)象,指定服務(wù)器名稱和端口號(hào)來請(qǐng)求連接。
Socket 類的構(gòu)造函數(shù)試圖將客戶端連接到指定的服務(wù)器和端口號(hào)。如果通信被建立,則在客戶端創(chuàng)建一個(gè) Socket 對(duì)象能夠與服務(wù)器進(jìn)行通信。
在服務(wù)器端,accept() 方法返回服務(wù)器上一個(gè)新的 socket 引用,該 socket 連接到客戶端的 socket。
連接建立后,通過使用 I/O 流在進(jìn)行通信,每一個(gè)socket都有一個(gè)輸出流和一個(gè)輸入流,客戶端的輸出流連接到服務(wù)器端的輸入流,而客戶端的輸入流連接到服務(wù)器端的輸出流。
TCP 是一個(gè)雙向的通信協(xié)議,因此數(shù)據(jù)可以通過兩個(gè)數(shù)據(jù)流在同一時(shí)間發(fā)送.以下是一些類提供的一套完整的有用的方法來實(shí)現(xiàn) socket。
整體流程
Socket編程主要涉及到客戶端和服務(wù)器端兩個(gè)方面,首先是在服務(wù)器端創(chuàng)建一個(gè)服務(wù)器套接字(ServerSocket),并把它附加到一個(gè)端口上,服務(wù)器從這個(gè)端口監(jiān)聽連接。端口號(hào)的范圍是0到65536,但是0到1024是為特權(quán)服務(wù)保留的端口號(hào),我們可以選擇任意一個(gè)當(dāng)前沒有被其他進(jìn)程使用的端口。
客戶端請(qǐng)求與服務(wù)器進(jìn)行連接的時(shí)候,根據(jù)服務(wù)器的域名或者IP地址,加上端口號(hào),打開一個(gè)套接字。當(dāng)服務(wù)器接受連接后,服務(wù)器和客戶端之間的通信就像輸入輸出流一樣進(jìn)行操作。
實(shí)例
下面是一個(gè)客戶端和服務(wù)器端進(jìn)行數(shù)據(jù)交互的簡(jiǎn)單例子,客戶端輸入正方形的邊長(zhǎng),服務(wù)器端接收到后計(jì)算面積并返回給客戶端,通過這個(gè)例子可以初步對(duì)Socket編程有個(gè)把握。
服務(wù)器端
public class SocketServer { public static void main(String[] args) throws IOException { // 端口號(hào) int port = 7000; // 在端口上創(chuàng)建一個(gè)服務(wù)器套接字 ServerSocket serverSocket = new ServerSocket(port); // 監(jiān)聽來自客戶端的連接 Socket socket = serverSocket.accept(); DataInputStream dis = new DataInputStream( new BufferedInputStream(socket.getInputStream())); DataOutputStream dos = new DataOutputStream( new BufferedOutputStream(socket.getOutputStream())); do { double length = dis.readDouble(); System.out.println("服務(wù)器端收到的邊長(zhǎng)數(shù)據(jù)為:" + length); double result = length * length; dos.writeDouble(result); dos.flush(); } while (dis.readInt() != 0); socket.close(); serverSocket.close(); }}客戶端
public class SocketClient { public static void main(String[] args) throws UnknownHostException, IOException { int port = 7000; String host = "localhost"; // 創(chuàng)建一個(gè)套接字并將其連接到指定端口號(hào) Socket socket = new Socket(host, port); DataInputStream dis = new DataInputStream( new BufferedInputStream(socket.getInputStream())); DataOutputStream dos = new DataOutputStream( new BufferedOutputStream(socket.getOutputStream())); Scanner sc = new Scanner(System.in); boolean flag = false; while (!flag) { System.out.println("請(qǐng)輸入正方形的邊長(zhǎng):"); double length = sc.nextDouble(); dos.writeDouble(length); dos.flush(); double area = dis.readDouble(); System.out.println("服務(wù)器返回的計(jì)算面積為:" + area); while (true) { System.out.println("繼續(xù)計(jì)算?(Y/N)"); String str = sc.next(); if (str.equalsIgnoreCase("N")) { dos.writeInt(0); dos.flush(); flag = true; break; } else if (str.equalsIgnoreCase("Y")) { dos.writeInt(1); dos.flush(); break; } } } socket.close(); }}實(shí)例二
可以看到上面的服務(wù)器端程序和客戶端程序是一對(duì)一的關(guān)系,為了能讓一個(gè)服務(wù)器端程序能同時(shí)為多個(gè)客戶提供服務(wù),可以使用多線程機(jī)制,每個(gè)客戶端的請(qǐng)求都由一個(gè)獨(dú)立的線程進(jìn)行處理。下面是改寫后的服務(wù)器端程序。
public class SocketServerM { public static void main(String[] args) throws IOException { int port = 7000; int clientNo = 1; ServerSocket serverSocket = new ServerSocket(port); // 創(chuàng)建線程池 ExecutorService exec = Executors.newCachedThreadPool(); try { while (true) { Socket socket = serverSocket.accept(); exec.execute(new SingleServer(socket, clientNo)); clientNo++; } } finally { serverSocket.close(); } }}class SingleServer implements Runnable { private Socket socket; private int clientNo; public SingleServer(Socket socket, int clientNo) { this.socket = socket; this.clientNo = clientNo; } @Override public void run() { try { DataInputStream dis = new DataInputStream( new BufferedInputStream(socket.getInputStream())); DataOutputStream dos = new DataOutputStream( new BufferedOutputStream(socket.getOutputStream())); do { double length = dis.readDouble(); System.out.println("從客戶端" + clientNo + "接收到的邊長(zhǎng)數(shù)據(jù)為:" + length); double result = length * length; dos.writeDouble(result); dos.flush(); } while (dis.readInt() != 0); } catch (IOException e) { e.printStackTrace(); } finally { System.out.println("與客戶端" + clientNo + "通信結(jié)束"); try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } }}上面改進(jìn)后的服務(wù)器端代碼可以支持不斷地并發(fā)響應(yīng)網(wǎng)絡(luò)中的客戶請(qǐng)求。關(guān)鍵的地方在于多線程機(jī)制的運(yùn)用,同時(shí)利用線程池可以改善服務(wù)器程序的性能。
總結(jié)
以上是生活随笔為你收集整理的c++ socket线程池_java 网络编程,Socket编程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 唐山市有安装旋转汽车座椅的吗?
- 下一篇: 机场到星海二院坐几路车?