Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

大家好,我是美有Huuuuugh。

帅哥的网络通信秘诀,在做网络编程的时候是不是像这样磨磨唧唧的写出来BufferedReader和BufferedWriter然后再慢吞吞的开几个线程呢?

1
2
3
4
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(),StandardCharsets.UTF_8));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8));
bw.write(message+"\n");
bw.flush();

😃太low了!
听好了,是帅哥的话,就应该把Socket封装起来,

Java实现

要先写一个Socket事件

1
2
3
public class SocketEvent {
public ConnectedSocket getConnectedSocket(){ return (ConnectedSocket)this; }//获取封装后的对象
}

然后再写一个MessageHandler接口用来存储事件

1
2
3
4
5
public interface MessageHandler {
void onMessageReceive(SocketEvent e, String message);//信息接收事件(必须覆写)
default void onClientConnected(SocketEvent e) { }//连接事件(默认无处理,可选覆写)
default void onClientDisconnected(SocketEvent e) { }//断开连接事件(默认无处理,可选覆写)
}

最后把它们封装进一个ConnectedSocket类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public class ConnectedSocket extends SocketEvent{
private Socket socket;
MessageHandler messageHandler;
public ConnectedSocket(Socket socket,MessageHandler messageHandler){//构造方法
this.socket = socket;
this.messageHandler = messageHandler;
new Thread(() -> {//lambda表达式创建线程
messageHandler.onClientConnected(this);
try {
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(),StandardCharsets.UTF_8));
while(true) {
String message = br.readLine();
messageHandler.onMessageReceive(this,message);
}
} catch (IOException e) {
disConnect();
}
}).start();
}
public void sendMessage(Object message){//发送消息
try {
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8));//获取输出流
bw.write(message+"\n");//写入信息
bw.flush();//刷新流
} catch (IOException ignored) { }
}

public void disConnect(){//断开Socket连接
try { socket.close(); } catch (IOException ignored) { }
messageHandler.onClientDisconnected(this);
}
public Socket getSocket(){//获取当前Socekt对象
if(socket.isConnected()){
return this.socket;
}else{
throw new RuntimeException("Socket连接断开,无法获取Socket");
}

}
}

看!这才是方便的Socket。

然后就可以写客户端的相关代码了!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class ClientMain {
public static void main(String[] args) {
Socket socket = null;
try {
socket = new Socket("127.0.0.1", 23333);
}catch (Exception ignored){}
ConnectedSocket s = new ConnectedSocket(socket, new MessageHandler() {
@Override
public void onClientConnected(SocketEvent e){
e.getConnectedSocket().sendMessage("你好!我是客户端嗷");
}
@Override
public void onMessageReceive(SocketEvent e, String message) {
System.out.println("我收到了服务器的信息:"+message);
}

@Override
public void onClientDisconnected(SocketEvent e){
System.out.println("诶呀呀,我掉线了");
}
});
}
}

同样的手法,这样封装的Socket在服务器上也可以“故技重施”,只不过服务端部分有一部分不一样(接收客户端的连接需要新开一个线程)。这里我使用了lambda表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(23333);
new Thread(() -> {
while(true){
try {
new ConnectedSocket(serverSocket.accept(), new MessageHandler() {
@Override
public void onClientConnected(SocketEvent e){
System.out.println(e.getConnectedSocket().getSocket().getInetAddress()+"连接了服务器");
}
@Override
public void onMessageReceive(SocketEvent e, String message) {
System.out.println("收到了来自客户端的信息:" + message);
e.getConnectedSocket().sendMessage("我收到了你发给我信息:"+message);
}
@Override
public void onClientDisconnected(SocketEvent e){
System.out.println(e.getConnectedSocket().getSocket().getInetAddress()+"与服务器连接断开");
}
});
} catch (IOException ignored) { }
}
}).start();
}
}

ne!是不是很简单?来,试试看!

评论