2020.2.28Java学习笔记——实时通信Socket实例

Java学习笔记——实时通信Socket实例

最近新学习Java,尝试一下Java的Socket编程,发现确实比C++要简便。
Java的Socket编程相比于C++在封装方面更加完善,所以对于Socket连接前的准备工作要比C++少去很多步骤。对比C++的Socket编程就知道Java代码可精简太多。

C++Socket实例

首先是Sever端中,省去了初始化ws2_32.dll动态库和选择dll版本的过程(即调用WSASTARTUP的过程)。其次是不需要手动设置sockaddr的网络地址等信息,也不需要bind地址信息的流程,在Java中服务端只需要设定监听的端口号(port)就可以打开Sever端,十分方便。接下来与Client端对接时也只需要一个accept函数来阻塞等待客户端的连接请求,相当于C++中的listen和accept的作用。

而在Client端中,网络地址信息这部分也只需要手动填入要通信的主机端的ip地址和端口号即可,在客户端中都不需要像C++那样调用connect函数,Java的Client端调用new Socket()函数创建套接字时就会自动发起连接请求,等于是创建Socket和连接Sever请求发送被封装在了同一个Socket()函数中。
(Java的Socket编程真的比C++能少写好多行)

Java Socket即时通讯实例:
Sever端:

import java.io.*;
import java.net.*;//导入socket所需的库
public class ServerSock {
    public static void main(String args[]) {
        try{
            ServerSocket server=null;
            try{
                //创建一个ServerSocket在端口4844监听客户请求
                server=new ServerSocket(4844);
            }catch(Exception e){
                e.printStackTrace();//出错,打印出错信息
            }
            Socket socket=null;
            try{
                //使用accept()阻塞等待客户请求,有客户请求到来则产生一个Socket对象,并继续执行
                socket=server.accept();
            }catch(Exception e){
                e.printStackTrace();
            }
            String line;
            //由Socket对象得到输入流,并构造相应的BufferedReader对象
            BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //由Socket对象得到输出流,并构造PrintWriter对象
            PrintWriter os=new PrintWriter(socket.getOutputStream());
            //由系统标准输入设备构造BufferedReader对象
            BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));
            //在标准输出上打印从客户端读入的字符串
            System.out.println("Client:"+is.readLine());
            //从标准输入读入一字符串
            line=sin.readLine();
            //通过while循环如果收到的信息字符串不为"bye",则将其打印出来并继续接收信息,该字符串为 "bye",则停止循环
            //即持续监听客户端,将其发来的每条信息打印出来
            while(!line.equals("bye")){
                //向客户端输出该字符串
                os.println(line);
                //刷新输出流,使Client马上收到该字符串
                os.flush();
                //在系统标准输出上打印读入的字符串
                System.out.println("Server:"+line);
                //从Client读入一字符串,并打印到标准输出上
                System.out.println("Client:"+is.readLine());
                //从系统标准输入读入一字符串
                line=sin.readLine();
            }
            
            os.close(); //关闭Socket输出流
            is.close(); //关闭Socket输入流
            socket.close(); //关闭Socket
            server.close(); //关闭ServerSocket
        }catch(Exception e){
            e.printStackTrace();
            
        }
    }
}

Client端:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class ClientSock {
    public static void main(String[] args) {
        try{
            //向本机的4844端口发出客户请求
            Socket socket=new Socket("127.0.0.1",4844);
            //由系统标准输入设备构造BufferedReader对象
            BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));
            //由Socket对象得到输出流,并构造PrintWriter对象
            PrintWriter os=new PrintWriter(socket.getOutputStream());
            //由Socket对象得到输入流,并构造相应的BufferedReader对象
            BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String readline;
            readline=sin.readLine(); //从系统标准输入读入一字符串
            //若从标准输入读入的字符串为 "bye"则停止循环
            while(!readline.equals("bye")){
                //将从系统标准输入读入的字符串输出到Server
                os.println(readline);
                //刷新输出流,使Server马上收到该字符串
                os.flush();
                //在系统标准输出上打印读入的字符串
                System.out.println("Client:"+readline);
                //从Server读入一字符串,并打印到标准输出上
                System.out.println("Server:"+is.readLine());
                readline=sin.readLine(); //从系统标准输入读入一字符串
            }
            os.close(); //关闭Socket输出流
            is.close(); //关闭Socket输入流
            socket.close(); //关闭Socket
        }catch(Exception e){
            e.printStackTrace();
        }

    }

}

这个例子也是我在网上学习时看别人的博文看到的。
java socket编程

实践中我看了一下,例子中的try{ }和catch ( ) { }类似C++中的一场处理关键字try和catch,用法和原理应该差不多。
例子中的is和os的输入输出流,我感觉和C++中的stdin和是stdout输入输出流可进行类比学习(不一定对)。
此外上面的实例中我发现一个问题,即在while循环中的代码还需进行优化,不然直接运行会产生一个问题:当Sever端或Client端一次性在输入流中连续发送多条信息时,另一端只能先接收到第一条信息,剩下的需要另一端自己发送了一条信息后才能接收到。下面的运行结果就是Sever端连续发送了两次"hello"后的运行结果。
2020.2.28Java学习笔记——实时通信Socket实例_第1张图片
2020.2.28Java学习笔记——实时通信Socket实例_第2张图片

你可能感兴趣的:(Java,Socket)