socket通讯流不关闭接收不到内容

socket 专栏收录该内容
1 篇文章 0 订阅

     socket通讯是基于tcp/ip协议的连接,该协议是基于ip和端口的,socket服务端跑起来之后会一直监控发送到某个端口上的数据,但是,socket所传输的内容不像文件一样,文件内容结尾是有标志符的,而socket传输的内容没有结尾标志符,所以socket传输内容如果不关闭流,read方法和readline方法在读取完数据后,会处于阻塞状态,一直等待数据传输过来,因为流没有关闭,会话还在进行。

像下面的代码:

客户端

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;


/*
 * 客户端
 */
public class Client {
    public static void main(String[] args) {
        // 1、创建客户端Socket,指定服务器地址和端口
        try {
            Socket  socket = new Socket("localhost", 8888);
            
            // 2、获取输出流,向服务器端发送信息
            OutputStream os = socket.getOutputStream();// 获取字节输出流
            // 将输出流包装为打印流
            PrintWriter pw = new PrintWriter(os);
            pw.write("admin 123");
            pw.flush();
            // 3、获取输入流,并读取服务器端的响应信息
            InputStream is = socket.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String info = null;
            while((info = br.readLine())!=null){
                System.out.println("我是客户端,服务器跟我说:"+new String(info.getBytes(), "UTF-8"));
            }
            
            
            
            // 4、关闭资源
            br.close();
            is.close();
            pw.close();
            os.close();
            socket.close();
            
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}


服务端:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;


/*
 * 基于TCP协议的Socket通信,实现用户登录
 * 服务器端
 */
public class Server {
    public static void main(String[] args) {
        try {
            // 1、创建一个服务器Socket,即ServerSocket,指定绑定的端口,并监听此端口
            ServerSocket serverSocket = new ServerSocket(8888);
            // 2、调用()方法开始监听,等待客户端的连接
            System.out.println("***服务器即将启动,等待客户端的连接***");
            Socket socket = serverSocket.accept();// 就会处于阻塞的状态,等待监听
            // 3、获取输入流,病读取客户端信息
            InputStream is = socket.getInputStream();// 字节输入流
            // 将字节流转换为字符流
            InputStreamReader isr = new InputStreamReader(is);
            // 为输入流添加缓冲
            BufferedReader br = new BufferedReader(isr);
            String info = null;
            while((info = br.readLine())!=null){
                System.out.println("我是服务器,读取客户端发过来的信息:"+new String(info.getBytes(), "UTF-8"));
            }
            
            // 4、作为服务器端,就需要响应客户端的请求,使用输出流来响应
            OutputStream os = socket.getOutputStream();
            PrintWriter pw = new PrintWriter(os);
            pw.write("欢迎您!");
            pw.flush();//调用flush()方法将缓冲输出
            
            // 5、关闭资源
            pw.close();
            os.close();
            br.close();
            isr.close();
            is.close();
            socket.close();
            serverSocket.close();
            
            
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        finally
        {
       
        }
    }

}


运行结果是服务端一直在读取,并阻塞到readline方法上。

只需要在每次交互后,关闭流就可以正常完成一次会话。

客户端: socket.shutdownInput();//关闭输入流

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;


/*
 * 基于TCP协议的Socket通信,实现用户登录
 * 服务器端
 */
public class Server {
    public static void main(String[] args) {
        try {
            // 1、创建一个服务器Socket,即ServerSocket,指定绑定的端口,并监听此端口
            ServerSocket serverSocket = new ServerSocket(8888);
            // 2、调用()方法开始监听,等待客户端的连接
            System.out.println("***服务器即将启动,等待客户端的连接***");
            Socket socket = serverSocket.accept();// 就会处于阻塞的状态,等待监听
            // 3、获取输入流,病读取客户端信息
            InputStream is = socket.getInputStream();// 字节输入流
            // 将字节流转换为字符流
            InputStreamReader isr = new InputStreamReader(is);
            // 为输入流添加缓冲
            BufferedReader br = new BufferedReader(isr);
            String info = null;
            while((info = br.readLine())!=null){
                System.out.println("我是服务器,读取客户端发过来的信息:"+new String(info.getBytes(), "UTF-8"));
            }
            socket.shutdownInput();//关闭输入流
            
            // 4、作为服务器端,就需要响应客户端的请求,使用输出流来响应
            OutputStream os = socket.getOutputStream();
            PrintWriter pw = new PrintWriter(os);
            pw.write("欢迎您!");
            pw.flush();//调用flush()方法将缓冲输出
            
            // 5、关闭资源
            pw.close();
            os.close();
            br.close();
            isr.close();
            is.close();
            socket.close();
            serverSocket.close();
            
            
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        finally
        {
       
        }
    }

}

客户端:socket.shutdownOutput();//关闭输出流

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;


/*
 * 客户端
 */
public class Client {
    public static void main(String[] args) {
        // 1、创建客户端Socket,指定服务器地址和端口
        try {
            Socket  socket = new Socket("localhost", 8888);
            
            // 2、获取输出流,向服务器端发送信息
            OutputStream os = socket.getOutputStream();// 获取字节输出流
            // 将输出流包装为打印流
            PrintWriter pw = new PrintWriter(os);
            pw.write("admin 123");
            pw.flush();
            socket.shutdownOutput();//关闭输出流
            // 3、获取输入流,并读取服务器端的响应信息
            InputStream is = socket.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String info = null;
            while((info = br.readLine())!=null){
                System.out.println("我是客户端,服务器跟我说:"+new String(info.getBytes(), "UTF-8"));
            }
            
            
            
            // 4、关闭资源
            br.close();
            is.close();
            pw.close();
            os.close();
            socket.close();
            
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

会发现可以完成一次会话了微笑

  • 3
    点赞
  • 1
    评论
  • 6
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值