這裏首先介紹幾個概念:BIO——同步阻塞IO、NIO——同步非阻塞IO、AIO——異步非阻塞IO
今天的例子是最簡單的一個例子,沒有引入多線程,僅僅是一個單線程阻塞的Socket例子,多線程的下次再繼續。
這樣子的例子僅僅供學習使用,基本上是沒有實用意義的,因爲在實際的應用中基本上是不止於一個Client的。
Server端得代碼如下:
Java代碼
package com.henushang.socket;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import com.henushang.socket.util.SocketUtils;
public class EchoServer {
private int port = 8000;
private ServerSocket serverSocket;
public EchoServer() throws Exception {
serverSocket = new ServerSocket(port);
System.out.println("waitting connet...");
}
public String echo(String msg) {
return "echo:" + msg;
}
public void service() {
Socket socket = null;
String msg = null;
while (true) {
try {
socket = serverSocket.accept();// 準備接受連接
System.out.println("new connection: " + socket.getInetAddress() + ":" + socket.getPort());
BufferedReader reader = SocketUtils.getReader(socket);// 輸入流
PrintWriter writer = SocketUtils.getWriter(socket);// 輸出流
while ((msg = reader.readLine()) != null) {// 接收消息
System.out.println(msg);
writer.println(echo(msg));// 發送消息
writer.flush();// 注意,在使用緩衝流在發送消息的時候最好進行強制刷新,否則,可能會由於緩衝區不滿而暫時不發送消息
if ("bye".equals(msg)) {
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}finally {
SocketUtils.close(socket);
}
}
}
public static void main(String[] args) {
try {
new EchoServer().service();
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.henushang.socket;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import com.henushang.socket.util.SocketUtils;
public class EchoServer {
private int port = 8000;
private ServerSocket serverSocket;
public EchoServer() throws Exception {
serverSocket = new ServerSocket(port);
System.out.println("waitting connet...");
}
public String echo(String msg) {
return "echo:" + msg;
}
public void service() {
Socket socket = null;
String msg = null;
while (true) {
try {
socket = serverSocket.accept();// 準備接受連接
System.out.println("new connection: " + socket.getInetAddress() + ":" + socket.getPort());
BufferedReader reader = SocketUtils.getReader(socket);// 輸入流
PrintWriter writer = SocketUtils.getWriter(socket);// 輸出流
while ((msg = reader.readLine()) != null) {// 接收消息
System.out.println(msg);
writer.println(echo(msg));// 發送消息
writer.flush();// 注意,在使用緩衝流在發送消息的時候最好進行強制刷新,否則,可能會由於緩衝區不滿而暫時不發送消息
if ("bye".equals(msg)) {
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}finally {
SocketUtils.close(socket);
}
}
}
public static void main(String[] args) {
try {
new EchoServer().service();
} catch (Exception e) {
e.printStackTrace();
}
}
}
客戶端代碼:
Java代碼
package com.henushang.socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import com.henushang.socket.util.SocketUtils;
public class EchoClient {
private String host = "127.0.0.1";
private int port = 8000;
private Socket socket ;
public EchoClient() throws Exception {
socket = new Socket(host, port);
}
public void talk() throws IOException {
try {
BufferedReader reader = SocketUtils.getReader(socket);
PrintWriter writer = SocketUtils.getWriter(socket);
// 讀取本地控制檯的消息
BufferedReader localReader = new BufferedReader(new InputStreamReader(System.in));
String msg = null;
while ((msg = localReader.readLine()) != null) {
writer.println(msg);
writer.flush();
System.out.println(reader.readLine());
if ("bye".equals(msg)) {
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}finally {
SocketUtils.close(socket);
}
}
public static void main(String[] args) throws Exception{
new EchoClient().talk();
}
}
package com.henushang.socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import com.henushang.socket.util.SocketUtils;
public class EchoClient {
private String host = "127.0.0.1";
private int port = 8000;
private Socket socket ;
public EchoClient() throws Exception {
socket = new Socket(host, port);
}
public void talk() throws IOException {
try {
BufferedReader reader = SocketUtils.getReader(socket);
PrintWriter writer = SocketUtils.getWriter(socket);
// 讀取本地控制檯的消息
BufferedReader localReader = new BufferedReader(new InputStreamReader(System.in));
String msg = null;
while ((msg = localReader.readLine()) != null) {
writer.println(msg);
writer.flush();
System.out.println(reader.readLine());
if ("bye".equals(msg)) {
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}finally {
SocketUtils.close(socket);
}
}
public static void main(String[] args) throws Exception{
new EchoClient().talk();
}
}
下面是我寫的一個工具類,做了一些重複的操作的彙集,如下:
Java代碼
package com.henushang.socket.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.nio.channels.SocketChannel;
public class SocketUtils {
public static PrintWriter getWriter(Socket socket) throws IOException {
OutputStream os = socket.getOutputStream();
return new PrintWriter(os);
}
public static PrintWriter getWriter(SocketChannel socketChannel) throws IOException {
return getWriter(socketChannel.socket());
}
public static BufferedReader getReader(Socket socket) throws IOException{
InputStream is = socket.getInputStream();
return new BufferedReader(new InputStreamReader(is, "UTF-8"));
}
public static BufferedReader getReader(SocketChannel socketChannel) throws IOException{
return getReader(socketChannel.socket());
}
public static void close(Socket socket) {
try {
if (socket != null) {
socket.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void close(SocketChannel socketChannel) {
try {
if (socketChannel != null) {
socketChannel.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.henushang.socket.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.nio.channels.SocketChannel;
public class SocketUtils {
public static PrintWriter getWriter(Socket socket) throws IOException {
OutputStream os = socket.getOutputStream();
return new PrintWriter(os);
}
public static PrintWriter getWriter(SocketChannel socketChannel) throws IOException {
return getWriter(socketChannel.socket());
}
public static BufferedReader getReader(Socket socket) throws IOException{
InputStream is = socket.getInputStream();
return new BufferedReader(new InputStreamReader(is, "UTF-8"));
}
public static BufferedReader getReader(SocketChannel socketChannel) throws IOException{
return getReader(socketChannel.socket());
}
public static void close(Socket socket) {
try {
if (socket != null) {
socket.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void close(SocketChannel socketChannel) {
try {
if (socketChannel != null) {
socketChannel.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
java socket多線程阻塞請點擊,http://www.shaccp.cn/