java實(shí)現(xiàn)socket客戶端連接服務(wù)端
本例只做簡(jiǎn)單功能演示,代碼并不嚴(yán)謹(jǐn),只是說明客戶端如何實(shí)現(xiàn)連接服務(wù)端簡(jiǎn)單代碼。
代碼在集成Eclipse工具下測(cè)試編譯運(yùn)行環(huán)境如下圖所示:

客戶端echoClient.java代碼:
package com.zhengzz.echo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
class EchoC{
private Socket socket;
public EchoC() {
// TODO Auto-generated constructor stub
try {
socket = new Socket("localhost", 60000);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void Client() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
BufferedReader lbr = new BufferedReader(new InputStreamReader(System.in));
String linestr = null;
while ((linestr = lbr.readLine()) != null) {
pw.println(linestr);
System.out.println(br.readLine());
if (linestr.equals("bye#")) {
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class echoClient {
public static void main(String[] args) {
new EchoC().Client();
}
}
服務(wù)端echoServer.java代碼:
package com.zhengzz.echo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
class EchoS{
private ServerSocket serverSocket;
public EchoS() {
try {
serverSocket = new ServerSocket(60000);
} catch (IOException e) {
e.printStackTrace();
}
}
public void Server() {
while (true) {
try {
Socket socket = serverSocket.accept();
System.out.println("client:" + socket.getInetAddress() + ":" + socket.getLocalPort());
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
String linestr;
while ((linestr = br.readLine()) != null) {
System.out.println(linestr);
pw.println("--->" + linestr);
}
} catch (IOException e) {
System.out.println("連接斷開:(");
}
}
}
}
public class echoServer {
public static void main(String[] args) {
new EchoS().Server();
}
}
我在Eclipse工具下直接調(diào)試結(jié)果如下:

下面我們?cè)賮砜匆粋€(gè) HelloWord 級(jí)別的 Java Socket 通信的例子。通訊過程:
先啟動(dòng) Server 端,進(jìn)入一個(gè)死循環(huán)以便一直監(jiān)聽某端口是否有連接請(qǐng)求。然后運(yùn)行 Client 端,客戶端發(fā)出連接請(qǐng)求,服務(wù)端監(jiān)聽到這次請(qǐng)求后向客戶端發(fā)回接受消息,連接建立,啟動(dòng)一個(gè)線程去處理這次請(qǐng)求,然后繼續(xù)死循環(huán)監(jiān)聽其他請(qǐng)求??蛻舳溯斎胱址蟀椿剀囨I,向服務(wù)器發(fā)送數(shù)據(jù)。服務(wù)器讀取數(shù)據(jù)后回復(fù)客戶端數(shù)據(jù)。這次請(qǐng)求處理完畢,啟動(dòng)的線程消亡。如果客戶端接收到 "OK" 之外的返回?cái)?shù)據(jù),會(huì)再次發(fā)送連接請(qǐng)求并發(fā)送數(shù)據(jù),服務(wù)器會(huì)為這次連接再次啟動(dòng)一個(gè)線程來進(jìn)行響應(yīng)。。。直到當(dāng)客戶端接收到的返回?cái)?shù)據(jù)為 "OK" 時(shí),客戶端退出。
服務(wù)端源代碼:
package com.defonds.socket.begin;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static final int PORT = 12345;//監(jiān)聽的端口號(hào)
public static void main(String[] args) {
System.out.println("服務(wù)器啟動(dòng)...\n");
Server server = new Server();
server.init();
}
public void init() {
try {
ServerSocket serverSocket = new ServerSocket(PORT);
while (true) {
// 一旦有堵塞, 則表示服務(wù)器與客戶端獲得了連接
Socket client = serverSocket.accept();
// 處理這次連接
new HandlerThread(client);
}
} catch (Exception e) {
System.out.println("服務(wù)器異常: " + e.getMessage());
}
}
private class HandlerThread implements Runnable {
private Socket socket;
public HandlerThread(Socket client) {
socket = client;
new Thread(this).start();
}
public void run() {
try {
// 讀取客戶端數(shù)據(jù)
DataInputStream input = new DataInputStream(socket.getInputStream());
String clientInputStr = input.readUTF();//這里要注意和客戶端輸出流的寫方法對(duì)應(yīng),否則會(huì)拋 EOFException
// 處理客戶端數(shù)據(jù)
System.out.println("客戶端發(fā)過來的內(nèi)容:" + clientInputStr);
// 向客戶端回復(fù)信息
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
System.out.print("請(qǐng)輸入:\t");
// 發(fā)送鍵盤輸入的一行
String s = new BufferedReader(new InputStreamReader(System.in)).readLine();
out.writeUTF(s);
out.close();
input.close();
} catch (Exception e) {
System.out.println("服務(wù)器 run 異常: " + e.getMessage());
} finally {
if (socket != null) {
try {
socket.close();
} catch (Exception e) {
socket = null;
System.out.println("服務(wù)端 finally 異常:" + e.getMessage());
}
}
}
}
}
}
客戶端源代碼:
package com.defonds.socket.begin;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
public class Client {
public static final String IP_ADDR = "localhost";//服務(wù)器地址
public static final int PORT = 12345;//服務(wù)器端口號(hào)
public static void main(String[] args) {
System.out.println("客戶端啟動(dòng)...");
System.out.println("當(dāng)接收到服務(wù)器端字符為 \"OK\" 的時(shí)候, 客戶端將終止\n");
while (true) {
Socket socket = null;
try {
//創(chuàng)建一個(gè)流套接字并將其連接到指定主機(jī)上的指定端口號(hào)
socket = new Socket(IP_ADDR, PORT);
//讀取服務(wù)器端數(shù)據(jù)
DataInputStream input = new DataInputStream(socket.getInputStream());
//向服務(wù)器端發(fā)送數(shù)據(jù)
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
System.out.print("請(qǐng)輸入: \t");
String str = new BufferedReader(new InputStreamReader(System.in)).readLine();
out.writeUTF(str);
String ret = input.readUTF();
System.out.println("服務(wù)器端返回過來的是: " + ret);
// 如接收到 "OK" 則斷開連接
if ("OK".equals(ret)) {
System.out.println("客戶端將關(guān)閉連接");
Thread.sleep(500);
break;
}
out.close();
input.close();
} catch (Exception e) {
System.out.println("客戶端異常:" + e.getMessage());
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
socket = null;
System.out.println("客戶端 finally 異常:" + e.getMessage());
}
}
}
}
}
}
注意: Socket 輸出流寫數(shù)據(jù)方法是 writeUTF 時(shí),輸入流讀取相關(guān)數(shù)據(jù)要用 readUTF。否則會(huì)拋 EOFException 異常。
相關(guān)文章
MybatisPlus搭建項(xiàng)目環(huán)境及分頁插件
Mybatis-Plus(簡(jiǎn)稱MP)是一個(gè)Mybatis的增強(qiáng)工具,在Mybatis的基礎(chǔ)上只做增強(qiáng)不做改變,為簡(jiǎn)化開發(fā)、提高效率而生,下面這篇文章主要給大家介紹了關(guān)于MybatisPlus搭建項(xiàng)目環(huán)境及分頁插件的相關(guān)資料,需要的朋友可以參考下2022-11-11
spring boot + mybatis如何實(shí)現(xiàn)數(shù)據(jù)庫(kù)的讀寫分離
這篇文章主要給大家介紹了關(guān)于spring boot + mybatis如何實(shí)現(xiàn)數(shù)據(jù)庫(kù)的讀寫分離的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用spring boot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09
SSH框架網(wǎng)上商城項(xiàng)目第29戰(zhàn)之使用JsChart技術(shù)顯示商品銷售報(bào)表
這篇文章主要為大家詳細(xì)介紹了SSH框架網(wǎng)上商城項(xiàng)目第29戰(zhàn)之使用JsChart技術(shù)顯示商品銷售報(bào)表,感興趣的小伙伴們可以參考一下2016-06-06
基于mybatis注解動(dòng)態(tài)sql中foreach工具的方法
這篇文章主要介紹了mybatis注解動(dòng)態(tài)sql中foreach工具方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
java中Timer定時(shí)器的使用和啟動(dòng)方式
這篇文章主要介紹了java中Timer定時(shí)器的使用和啟動(dòng)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12

