socket 简要总结

1 篇文章 0 订阅

先开启服务端,再开启客户端,否则Connection refused

如果客户端没有发送结束标识,如socket.shutdownOutput()或者socket.close(),服务端读取数据Connection reset,反之亦然

客户端Client的时候, 如果存在网络问题, 为了避免网络问题,造成客户端长时间等待, 此时要设置一个TimeOut

clientSocket = new Socket();
 //这个TimeOut是连接等待时间
clientSocket.connect(tcpAddress, timeOut);
  1. 当客户端已经连接, 每次收到一个数据, 客户端将启动处理, 假如服务器长久不发数据, 此时客户端会阻塞等待, 为了避免这个时候的等待, 可以设置一个超时
clientSocket.setSoTimeout(timeOut);
如何告知对方已发送完命令
socket 关闭
socket.close()  
  • socket关闭连接,那边如果有服务端给客户端反馈信息,此时客户端是收不到的

  • 如果客户端想再次发送消息,需要重现创建Socket连接

    通过Socket关闭输出流的方式
socket.shutdownOutput() 

而不是outputStream.close() (outputStream为发送消息到服务端打开的输出流)):

outputStream.close();

如果关闭了输出流,那么相应的Socket也将关闭,和直接关闭Socket一个性质

socket.shutdownOutput()是将客户端输出流关闭,此时,如果服务端有信息返回,则客户端是可以正常接受的,如果没有,直接关闭Socket

  • 不能再次发送消息给服务端,如果再次发送,需要重新建立Socket连接
通过约定符号

双方约定一个字符或者一个短语,来当做消息发送完成的标识,通常这么做就需要改造读取方法

假如约定单端的一行为end,代表发送完成,例如下面的消息,end则代表消息发送完成:

hello wakala
end

服务端读取操作:

Socket socket = server.accept();
// 建立好连接后,从socket中获取输入流,并建立缓冲区进行读取
BufferedReader read=new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8"));
String line;
StringBuilder sb = new StringBuilder();
while ((line = read.readLine()) != null && "end".equals(line)) {
  //注意指定编码格式,发送方和接收方一定要统一,建议使用UTF-8
  sb.append(line);
}
通过指定长度

记录异常:Connection reset

当客户端用readLine读取数据时,readline()方法会读到流结束或者\n的时候返回

客户端:
InputStream inputStream = socket.getInputStream();
 BufferedReader bufferedReader = new BufferedReader(new         InputStreamReader(inputStream,DEFAULT));
            StringBuilder builder = new StringBuilder();
            String line = bufferedReader.readLine();
            builder.append(line);
服务端:
String linebreak = System.getProperty("line.separator","\n");
OutputStream outputStream = socket.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new     OutputStreamWriter(outputStream));
bufferedWriter.write("response");
   // bufferedWriter.write(linebreak);//添加换行符
bufferedWriter.flush();

服务端如果不关闭输出流或者在消息的结尾没有发送换行符\n时,客户端会报Connection reset

如果消息加了换行符,并且服务端没有关闭,在客户端读取时,这样写同样会报错:


InputStream inputStream = socket.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new        InputStreamReader(inputStream));
 StringBuilder builder = new StringBuilder();
 String line;
    while ((line = bufferedReader.readLine())!= null){
       builder.append(line);
    }  
 //因为 第一次bufferedReader.readLine()已经读完,socket连接已经释放,再次在while()中读取就会 //Connection reset
// 所以去掉while循环, 
 StringBuilder builder = new StringBuilder();
 String line = bufferedReader.readLine();
 builder.append(line);
    
  还有:
  //客户端这种方式读取,服务端不需要加换行符号
 byte[] bytes = new byte[1024];
  int len;
  StringBuilder sb = new StringBuilder();
  while ((len = inputStream.read(bytes))!= - 1){
          String part = new String(bytes,0,len,DEFAULT);
         //println("result part=="+part);
          sb.append(part);
   }
  客户端一直读取也会报Connection reset
 解决方法:
 判断inputStream.available()方法,这种方法在读写操作前先得知数据流里有多少个字节可以读取
  byte[] bytes = new byte[1024];
        do{
                 len = inputStream.read(bytes);
                 if (len!=-1){
                     String sss = new String(bytes,0,len,DEFAULT);
                     println("result part=="+sss);
                     sb.append(sss);
                 }
              }while(inputStream.available()!= 0);
 
 

参考:JAVA通信系列一:Java Socket技术总结

Java Socket编程基础及深入讲解

Connection reset :readline 引起的socket读取异常

Socket的长连接和短连接

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值