Fork me on GitHub

SocketDemo学习笔记

一个简易的实现全双工通信的 Socket Demo 程序。

推荐阅读:
ServerSocket connection
Java 网络编程精解之 ServerSocket 用法详解一

源码

先看两个封装类 ReaderWriter

  • Reader接收输入值,生成OutputStream
  • Writer读入InputStream的值,打印到console上。
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
package org.aeadt.learn;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Scanner;

public class Reader extends Thread {
OutputStream out;

public Reader(OutputStream out) {
this.out = out;
setDaemon(true);
}

@Override
public void run() {
Scanner s = new Scanner(System.in);
try {
while (true) {
String str = s.nextLine();
out.write(str.getBytes());
out.write('\n');
out.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
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
package org.aeadt.learn;

import java.io.IOException;
import java.io.InputStream;

public class Writer extends Thread {
InputStream in;

public Writer(InputStream in) {
this.in = in;
}

@Override
public void run() {
try {
while (true) {
int b;
while ((b = in.read()) != -1) {
System.out.write(b);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

然后就是模拟服务器和客户机的ServerDemoClientDemo了。

  • 首先建立 Socket 连接,服务端创建监听接口:new ServerSocket(8000);,表示绑定接口 8000,如果绑定失败会抛出IOException。如果设为 0,则由 OS 任意分配端口(很少这么做)。
  • 可能会有多个 Client 向 Server 发送连接请求,即执行Socket s = new Socket("localhost", 8000);的程序。所以服务器会将请求先放入一个队列中(通常容量为 50,超过 50 后将拒绝连接)。
  • 如果 Client 的请求被加入队列中,此时new Socket()将会正常返回。
  • Server 调用accept()方法,从队列中取出连接请求,建立连接完成。
  • 之后 Client 和 Server 可以通过 ReaderWriter工具完成细节通信。
  • 此处还缺一个close()的操作,略去不提。
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
package org.aeadt.learn;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerDemo {

public static void main(String[] args) throws IOException {
ServerDemo server = new ServerDemo();
server.start();
}

public void start() throws IOException {
ServerSocket ss = new ServerSocket(8000);
System.out.println("等待客户的连接");
Socket s = ss.accept();
System.out.println("客户连接成功:" + s.getInetAddress());
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();
Reader r = new Reader(out);
r.start();
Writer w = new Writer(in);
w.start();
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package org.aeadt.learn;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class ClientDemo {
public static void main(String[] args) throws IOException {
ClientDemo client = new ClientDemo();
client.open();
}


public void open() throws IOException {
Socket s = new Socket("localhost", 8000);
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();
new Reader(out).start();
new Writer(in).start();
}
}
-------------The End-------------