1、 服务器端处理流程
接触一种技术,首先都要熟悉它的生命周期,这样才能从大局上看每个流程的细节。才有居高临下,势如劈竹的架势。加深我们对这种技术的理解。对于socket网络编程,我们现在来看看socket服务器的生命周期。
socket程序,一般情况下,都是服务器与客户端成双成对出现。
服务器端socket的生命周期为:监听服务器端口,接受客户端连接,获取客户端输入、输出流,处理业务逻辑、发送响应信息,关闭客户端连接,关闭服务区监听。详情如下所示:
2、 客户端处理流程
socket程序的客户端的处理流程与服务器的相似,生命周期为:创建客户端socket,获取服务器输入、输出流,处理业务逻辑、发送相应信息、关闭客户端连接。详情如下所示:
3、 服务端与客户端的交互
4、 实例代码
首先是写一个Server类,这个类用来监听9999端口,并从这个端口接收消息然后输出,当收到“bye”时退出。
public class MyServer {
public static void main(String[] args) throws IOException {
int port = 9999;
// 监听服务器端口
ServerSocket server = new ServerSocket(port);
System.out.println("listening on " + port);
// 接受一个客户端连接
Socket socket = server.accept();
System.out.println("the client " + socket.getInetAddress().getHostAddress() + " has connected!");
// 获取客户端的输入流
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 获取客户端的输出流
PrintWriter out = new PrintWriter(socket.getOutputStream());
while (true) {
String msg = in.readLine();
System.out.println("---------------------------");
System.out.println("Server received " + msg);
if (msg.equals("bye")) {
System.out.println("Server stoped!");
out.print("Server said 88");
out.flush();
break;
} else {
// 想客户端发送信息
System.out.println("Server said " + msg);
out.print("Server said " + msg);
out.flush();
}
}
socket.close();
server.close();
}
}
然后是一个Client类,这个类连接上面启动的Server类,然后接收任何用户输入,当遇到回车时发送字符串到Server上,当输入“bye”是退出。
public class MyClient {
public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException {
Scanner reader = new Scanner(System.in);
// 创建客户端socket
Socket client = new Socket("localhost", 9999);
// 获取客户端的输出流(获取服务器端的输入流)
PrintWriter out = new PrintWriter(client.getOutputStream());
// 获取客户端的输入流(获取服务器端的输出流)
InputStream in = client.getInputStream();
while (true) {
System.out.println("---------------------------");
System.out.println("Input Something: ");
String msg = reader.nextLine();
System.out.println("Client sended " + msg);
out.println(msg);
out.flush();
Thread.sleep(1000);
byte[] buff = new byte[in.available()];
in.read(buff);
System.out.println(new String(buff, "UTF-8"));
if (msg.equals("bye")) {
System.out.println("Client stop!");
break;
}
}
out.close();
client.close();
}
}
5、 结果
首先运行MyServer类,然后MyClient类,然后在MyClient的控制台输入任意字符。
客户端
---------------------------
Input Something:
11
Client sended 11
Server said 11
---------------------------
Input Something:
22
Client sended 22
Server said 22
---------------------------
Input Something:
bye
Client sended bye
Server said 88
Client stop!
服务器端
listening on 9999
the client 127.0.0.1 has connected!
---------------------------
Server received 11
Server said 11
---------------------------
Server received 22
Server said 22
---------------------------
Server received bye
Server stoped!
6、 总结
这个例子中,客户端每一次请求,服务端都会建立一次短连接。在现实环境中,这种方法是不可行的,因为服务器中每一次创建socket连接,都会消耗cpu和内存资源。很多情况下,都会使用长连接的方式来处理经常要进行数据通信的场景。