`
jacky1118sally
  • 浏览: 13868 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

socket 通信基本类(invalid type code: AC和BlockDataInputStream.peekByte异常)

    博客分类:
  • J2SE
阅读更多
由于需要做个一个CS的系统,需要实现服务器和客户端的交互,那么这个通讯的基本类就很重要了 为了写这个基本类 真是费了一番周折 。要把这个做好 多线程需要理解的比较好。因为 服务器需要一直监听客户端的请求,而客户端也要一直监听 服务器的请求。

首先是 客户端:

package client;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client implements Runnable{
private Socket client;
private String ip = "127.0.0.1";
private int port = 8888;
private ObjectOutputStream out;

//连接     
public void conn(){
         try {
          
     client = new Socket(ip,port);
   
     if(client.getOutputStream()!=null) {
    
      out = new ObjectOutputStream(client.getOutputStream());
    
     }
   
   
    } catch (UnknownHostException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
        }            
                   
        //启动线程
public void run() { 
   try {  
ObjectInputStream in = new ObjectInputStream(client.getInputStream());

       boolean flag = true;
    while(flag){
     Object obj = in.readObject();
     if(obj!=null){
      String s = (String)obj;
      System.out.println("收到服务器消息:" + s);
      if(s.equals("shutdown")){
       flag = false;
      }
     }
    }
    System.out.println("ByeBye!");
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   } catch (ClassNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
}

//向服务器发送object
public void sendMessage(Object obj){
   //ObjectOutputStream out=null;
   try {

            out.writeObject(obj);
            out.flush();
         
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }

}


}

服务器端有两个类:

主类:

package server;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class MainServer implements Runnable{
private int port = 8888;
List arr = new ArrayList();

//初始化方法
public void init(int port) {
   this.port = port;
}

public void run() {
   try {
  
    ServerSocket server = new ServerSocket(port);
    System.out.println("--------服务器启动---------");
    while (true) {
     Socket socket = server.accept();
     System.out.println("--------客户端连接---------");
   
     String ip = socket.getLocalSocketAddress()+"";
     ip = ip.substring(1,10);
   
     ServerAccept acc = new ServerAccept();
     acc.init(socket,ip);
     arr.add(acc);//将客户端放入数组中
     acc.start();
   
   
    }
   } catch (Exception e) {
 
    e.printStackTrace();
   }    
}

//遍历数组,对指定IP发送object
public void sendMessage(String ip,Object obj) {


for(int i=0;i<arr.size();i++) {
   ServerAccept a = (ServerAccept)arr.get(i);
   String temp = a.getIp();
   if(temp.equals(ip)) {
    try {
     a.getOut().writeObject(obj);
     a.getOut().flush();
    } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
  
    }
   }

}


}




}



线程类:


package server;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

public class ServerAccept extends Thread {

//private ObjectInputStream in;
private ObjectOutputStream out;
private String ip;
private String s;
private Socket socket;



    public void init(Socket socket,String ip) {
 
   try {
    this.socket=socket;
    this.out = new ObjectOutputStream(socket.getOutputStream());
    this.ip=ip;
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
}

   
   
//一直监听客户端发送到来的消息
public void run() {

   boolean flag = true;
   try {
  
    ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
        while(flag){
   
      Object obj = in.readObject();
       
      if(obj!=null){
       String s = (String)obj;
       if(s.equals("关闭")){
      
        flag = false;
        continue;
       }
       System.out.println("客户端消息:" + s);
      }
    
     


     }
  
   
    // System.out.println("ByeBye!");
       
   } catch (IOException e) {
    // TODO Auto-generated catch block
    flag = false;
    e.printStackTrace();
   } catch (ClassNotFoundException e) {
    // TODO Auto-generated catch block
    flag = false;
    e.printStackTrace();
   }
 
   }

public String getIp() {
   return ip;
}


public ObjectOutputStream getOut() {
   return out;
}


public String getS() {
   return s;
}

 
}
 


在这个过程中 主要遇到了 最令人 头疼的 java.io.StreamCorruptedException: invalid type code: AC 异常。

一直不明白怎么回事 后来才知道 原来是 ObjectOutputStream 流只可以对应,不可以生成多次,

当时我把 红色的那一段代码 放在了 while 里面 结果一直报错,只可以发送一次,第二次就不行,因为你又new 了一个 ObjectOutputStream 那是不可以的 同一个 socket。

还有一个异常就是 java.io.ObjectInputStream$BlockDataInputStream.peekByte 异常

这个意思我查阅了一下 原来是 到达了文件的末尾,程序却没有正常结束读取文件内容 也就是蓝色的这一段 会抛异常 因为无法终止while 。 后来我 要结束流的时候就发送消息“关闭” 然后就 关闭了。socket是面向连接的 所以终止任何一方都会异常吧 ,现在都是捕获到异常然后 关闭 呵呵呵 。不过应该有好的方法。 我毕竟写的很多缺陷了。

这个基本类 实现了监听,主要就是在于 线程中的 连个while 循环 在一直等待着对方的消息,也是这里不好处理。

希望大家提出意见 改进啊


测试类:

package client;

public class ClientTest {


public static void main(String []args) {
 
   Client client = new Client();
 
     client.conn();
 
   new Thread(client).start();
 
   client.sendMessage("我发送的消息!");
   client.sendMessage("这也是我发送的消息!");
   client.sendMessage("关闭");

 
}
                                 
     服务器:

/*
* ServerForm.java
*
* Created on __DATE__, __TIME__
*/

package server;

import java.util.HashMap;

/**
*
* @author __USER__
*/
public class ServerForm extends javax.swing.JFrame {

/** Creates new form ServerForm */
public ServerForm() {
   initComponents();
}

/*
* 创建server对象
*
*/
MainServer server = new MainServer();

//ServerTest ser = new ServerTest();

/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/

//GEN-BEGIN:initComponents
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {

   jButton1 = new javax.swing.JButton();
   jTextField1 = new javax.swing.JTextField();
   jButton2 = new javax.swing.JButton();

   setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

   jButton1.setText("\u542f\u52a8\u670d\u52a1\u5668");
   jButton1.addActionListener(new java.awt.event.ActionListener() {
    public void actionPerformed(java.awt.event.ActionEvent evt) {
     jButton1ActionPerformed(evt);
    }
   });

   jButton2.setText("\u53d1\u9001\u6d88\u606f");
   jButton2.addActionListener(new java.awt.event.ActionListener() {
    public void actionPerformed(java.awt.event.ActionEvent evt) {
     jButton2ActionPerformed(evt);
    }
   });

   javax.swing.GroupLayout layout = new javax.swing.GroupLayout(
     getContentPane());
   getContentPane().setLayout(layout);
   layout
     .setHorizontalGroup(layout
       .createParallelGroup(
         javax.swing.GroupLayout.Alignment.LEADING)
       .addGroup(
         javax.swing.GroupLayout.Alignment.TRAILING,
         layout
           .createSequentialGroup()
           .addContainerGap(47, Short.MAX_VALUE)
           .addGroup(
             layout
               .createParallelGroup(
                 javax.swing.GroupLayout.Alignment.LEADING)
               .addComponent(jButton1)
               .addGroup(
                 layout
                   .createSequentialGroup()
                   .addComponent(
                     jTextField1,
                     javax.swing.GroupLayout.PREFERRED_SIZE,
                     139,
                     javax.swing.GroupLayout.PREFERRED_SIZE)
                   .addGap(
                     18,
                     18,
                     18)
                   .addComponent(
                     jButton2)))
           .addContainerGap()));
   layout
     .setVerticalGroup(layout
       .createParallelGroup(
         javax.swing.GroupLayout.Alignment.LEADING)
       .addGroup(
         javax.swing.GroupLayout.Alignment.TRAILING,
         layout
           .createSequentialGroup()
           .addContainerGap(76, Short.MAX_VALUE)
           .addComponent(jButton1)
           .addGap(70, 70, 70)
           .addGroup(
             layout
               .createParallelGroup(
                 javax.swing.GroupLayout.Alignment.BASELINE)
               .addComponent(jButton2)
               .addComponent(
                 jTextField1,
                 javax.swing.GroupLayout.PREFERRED_SIZE,
                 javax.swing.GroupLayout.DEFAULT_SIZE,
                 javax.swing.GroupLayout.PREFERRED_SIZE))
           .addGap(104, 104, 104)));

   pack();
}// </editor-fold>
//GEN-END:initComponents

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {

   String s = jTextField1.getText();
   server.sendMessage("127.0.0.1", s);
   jTextField1.setText("");
}

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {

   new Thread(server).start();
 
}

/**
* @param args the command line arguments
*/
public static void main(String args[]) {

   java.awt.EventQueue.invokeLater(new Runnable() {
    public void run() {
     new ServerForm().setVisible(true);
    }
   });

}

//GEN-BEGIN:variables
// Variables declaration - do not modify
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JTextField jTextField1;
// End of variables declaration//GEN-END:variables

}                             


说明:

1,运行serverForm,点击启动服务器。
2,运行clientTest,启动一个客户端。
3,在form界面,输入字符串,点击发送,会发送给服务器,在控制台输出。

由于我用的是 MyEclipse 8.0 这个界面是生成的 如果版本低的话 可能要导架包哈 呵呵
分享到:
评论

相关推荐

    Caused by: android.system.ErrnoException: write failed: ENOSPC (

    ### 错误解析:Caused by: android.system.ErrnoException: write failed: ENOSPC (No space left ...通过以上的方法和技术手段,可以有效地避免因存储空间不足而导致的应用程序异常,提高用户体验。

    MQTT协议通讯,支持JS、JAVA、微信小程序客户端

    它以较少的代码和最小化的网络流量为目标,使得其成为物联网(IoT)领域中最常采用的通信协议之一。 #### 一、Broker-ActiveMQ **ActiveMQ**是Apache出品的一个非常优秀的消息中间件,支持多种消息传输协议,包括...

    org.xml.sax.SAXException: Invalid element

    NULL 博文链接:https://wilian.iteye.com/blog/1992365

    启动异常invalid constant type:15的解决方案

    "启动异常invalid constant type:15"是一种常见的Java异常,主要是由于Java类加载机制中的一个bug所引起的。在Java中,类加载器会将class文件加载到内存中,并将其转换成Java类对象。但是,在某些情况下,类加载器...

    invalid_request_error如何解决.md

    在开发中,尤其是在与HTTP请求交互时,遇到"invalid_request_...此外,也要记住在解决问题的过程中,对异常进行妥善处理,这不仅可以帮助我们得到错误的具体信息,而且有助于我们更好地理解和预防这类错误再次发生。

    解决:dubbo找不到dubbo.xsd报错

    - cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'dubbo:application'. - schema_reference.4: Failed to read schema document '...

    Invalid Image Format(解决方案).md

    在处理项目中遇到的Invalid Image Format问题时,可以采取多种解决策略。首先,确保图像文件的路径正确无误,并且文件格式兼容你的程序。常见的图像格式包括.jpg、.png和.gif等。要检查文件路径,可以使用Python的...

    Java连接达梦数据库驱动dm_jdbc

    Java连接达梦数据库驱动dm_jdbc: ...dm_jdbc\Dm7Dictionary.jar dm_jdbc\Dm7JdbcDriver14.jar dm_jdbc\Dm7JdbcDriver15.jar dm_jdbc\Dm7JdbcDriver16.jar dm_jdbc\Dm7JdbcDriver17.jar dm_jdbc\dmgeo_1.6.jar ...

    图片处理 javax.imageio.IIOException: Unsupported Image Type

    在Java编程环境中,图片处理是一项常见的任务,但有时可能会遇到“javax.imageio.IIOException: Unsupported Image Type”的错误。这个异常通常表示Java的`ImageIO`类库无法识别或支持所尝试读取或写入的图像格式。...

    org.eclipse.paho.android.service-1.1.1-sources.jar

    修复了MqttAndroidClient会出现throw new IllegalArgumentException Invalid ClientHandle报错,而源github中代码未更新解决,所以经过重新编译,生成新的jar包,增加IllegalArgumentException异常处理,替换关联的...

    Java 一些实际应用案例 demo

    通过ServerSocket和Socket类,可以创建客户端和服务器端的通信连接。 10. **API的使用**:Java标准库提供了丰富的API,如Swing或JavaFX用于图形用户界面(GUI)开发,JDBC用于数据库操作,JAXP和DOM/SAX用于XML处理...

    解决Jave在linux下转为MP3时为0字节或其他异常或转码后只有1分钟时长

    2、可以转换,可以播放,但是有个异常:it.sauronsoftware.jave.EncoderException: video:0kB audio:1301kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.019516% 通过解读源码,在...

    InvalidArgument-The argument is invalid(解决方案).md

    InvalidArgument-The argument is invalid(解决方案).md

    多线程Socket.

    多线程Socket阻塞模式下通信的例子 BCB-Socket阻塞模式通讯测试(多线程) 作者:Sncel(地狱情人) QQ:6522203 指导:invalid(空心菜) QQ:309283 http://bcb.vicp.net 测试方法: 在单机上测试: 如果有多个客户...

    WebGLInvalidEnumError(解决方案).md

    通过功能检测和文档验证,可以有效地解决这类问题,保证WebGL应用的稳定性和可靠性。 此外,进行充分的测试以及查阅相关文档和样例代码,可以进一步确保枚举值的正确使用,从而避免因错误的枚举值导致的渲染失败或...

    invalid interface type(解决方案).md

    invalid interface type(解决方案).md

    Invalid name=”com.alibaba.dubbo.config.ProtocolConfig#0″

    使用@EnableDubbo启用dubbo, 配置dubbo.protocol.xxx相关属性,不设置dubbo.protocol.id,启动应用将会抛出异常. java.lang.IllegalStateException: Invalid name=“com.alibaba.dubbo.config.ProtocolConfig#0” ...

    ftp连接不上出现500 Invalid PORT Command.错误

    解析主机为: 112.125.43.138 已连接. 正等待响应. 220 Microsoft FTP Service USER 123000 331 Password required for 123. ...500 Invalid PORT Command. PASV 227 Entering Passive Mode (10,247,80,183,117,51).

    ZK框架:Ajax开发实战.5.rar

    ZK框架 :Ajax开发实战.5.rar

Global site tag (gtag.js) - Google Analytics