网络编程---socket编程通信

  一直感觉socket这个东西挺神秘的 ,觉得是大牛级别的才能驾轻就熟。今天碰巧看了一下socket的相关资料,通过socket实现客户端和服务端的通信,从实战中去体验socket的用处。

   先给大家上一张图

这张图大致就是tcp协议和udp协议的分布范围,其中,socket负责的是传输层之间的通信

socket是基于应用服务与TCP/IP通信之间的一个抽象,他将TCP/IP协议里面复杂的通信逻辑进行分装,对用户来说,只要通过一组简单的API就可以实现网络的连接

简而言之,socket已经封装成相应的方法,我们调用相应的方法即可进行socket的使用。

一,创建服务端和客户端的连接

服务端:

public static void main(String[] args) {
        try {
            //初始化服务端
            ServerSocket serverSocket = new ServerSocket(9999);
            //等待客户端链接
            Socket socket = serverSocket.accept();
            //获取输入流
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //读取一行数据
            String str = bufferedReader.readLine();
            //输出打印
            System.out.println("服务端:"+str);
        }catch (IOException e){
            //抓取初始化服务端的io异常
            e.printStackTrace();
        }

    }

客户端:

public static void main(String[] args) {
        try {
            //获取服务端的链接
            Socket socket = new Socket("127.0.0.1",9999);
            //写入输入流
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            //创建输入文字
            String str = "你好";
            bufferedWriter.write(str);
            //刷新输入流
            bufferedWriter.flush();
            //关闭socket的输入流----此处与close不同,close后会完全关闭,无法接受服务端反馈的信息
            socket.shutdownOutput();
        }catch (IOException e){
            e.printStackTrace();
        }
    }

注意:1.socket连接需要先启动服务端,再启动客户端,这样客户端才能通过端口号去找到开启服务的socket服务端

           2.在客户端中,需要关闭资源,也就是shutdowmOutPut()方法,这个方法的好处是,如果后期做到服务端响应客户端的消息时,客户端是可以接收到的,如果调用的是close()方法,那就真的是关掉整个资源,再也收不到其他消息了。

将服务端和客户端的代码编写完成后,依次启动服务端和客户端,服务端会立即接收到客户端发的信息,如图:

这代表socket中服务端和客户端完成了一次通信,我们在服务端调用相应的方法进行服务端的创建,客户端也是,运用基本的socketAPI完成了一次通信,也是一次对socket的基本知识的熟悉。

二,思考

  1.客户端可以发送多条消息吗?

  2.服务端能不能响应客户端的信息呢?

  3.客户端和服务端能不能正常发信息进行交流?

  答案当然是可以的,只不过需要我们去不断的变通。

三,客户端发送多条消息

服务端:

public static void main(String[] args) {
        try {
            ServerSocket serverSocket = new ServerSocket(9999);
            //等待客户端链接
            Socket socket = serverSocket.accept();
            //获取输入流
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream(),"utf-8"));
            String str;
            //循环判断是否为空
            while((str=bufferedReader.readLine())!=null){
                System.out.println("客户端:"+str);
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }

客户端:

public static void main(String[] args) {
        try {
            //获取服务端的链接
            Socket socket = new Socket("127.0.0.1", 9999);
            //写入输入流
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            //写入输出流
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in,"utf-8"));
            //循环
            while(true){
                String strinput = bufferedReader.readLine();
                bufferedWriter.write(strinput);
                bufferedWriter.write("\n");
                bufferedWriter.flush();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

这边在客户端和服务端都加了一个循环,客户端循环读取输入的值,服务端循环读取输出的值,最后如图:

客户端实现

服务端实现

通过一个循环,就可以解决发送多条通信的问题

四,服务端和客户端进行互通交流

   服务端和客户端想要进行互相通信,那就需要两者具备接收和发送信息的功能,并且相应的创建文件的位置是比较重要的,否则会出现服务端永远响应一条信息,错误实例如图:

此图是服务端代码有误,就像foreach循环一样,初始化代码的地方有误,会导致后续的代码取值全部相同,这里就是在第二行全部取空值。

正确服务端代码如下;

public static void main(String[] args) {
        try {
            ServerSocket serverSocket = new ServerSocket(9999);
            //等待客户端链接
            Socket socket = serverSocket.accept();
            //获取输出流
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "utf-8"));

            //循环判断是否为空
            //while((str=bufferedReader.readLine())!=null){
            Scanner sc = new Scanner(System.in);
            while (true) {
                //获取输入流
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "utf-8"));
                String str = bufferedReader.readLine();
                System.out.println("客户端:" + str);
                System.out.println("请反馈客户端");
                String strs = sc.nextLine();
                bufferedWriter.write(strs);
                bufferedWriter.write("\n");
                bufferedWriter.newLine();
                bufferedWriter.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

客户端代码:

public static void main(String[] args) {
        try {
            //获取服务端的链接
            Socket socket = new Socket("127.0.0.1", 9999);
            //循环
            Scanner scanner = new Scanner(System.in);
            while(true){
                System.out.println("请输入发送消息内容:");
                String str = scanner.nextLine();
                //写入输入流
                BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                bufferedWriter.write(str);
                bufferedWriter.write("\n");
                bufferedWriter.newLine();
                bufferedWriter.flush();
                //写入输出流
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                String ret = bufferedReader.readLine();
                System.out.println("服务器端返回过来的是: " + ret);
                /*String ret;
                while((ret=bufferedReader.readLine())!=null){
                    System.out.println("服务器端返回过来的是: " + ret);
                }*/
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

通信客户端:

通信服务端:

这样就实现了服务端和客户端之间的通信。

现在是做一些这方面的积累,等待真正使用的时候不至于手忙脚乱。

让我们一起好好学习天天向上吧!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值