我刚学完SE ~ 所以做了下面一个项目来检验下自己SE方面的知识--"一个简单的网上购票系统,有服务器,可以连接多个客服端,有涉及gui、socket、线程方面," 大部分功能已经实现,但是却有一个bug。客户端买票了之后,服务器端的数据被更新了,但是发送回去客户端,想更新界面表格的时候却失败了。客户端接受到的是旧的列表信息。 我已经debug 两个小时啦~快崩溃了~
求大神解救~!!!! 个人怀疑是io处理出错了~~ ps:如果有设计方面的意见或者建议也可以跟我说~ 整个程序都是我自己想得~ 但是我觉得还有更好的方法实现~ 或者更好的设计模式应用。 额 设计模式其实我还没学到~ 只了解到皮毛。
io ,错误,debug ,SE

解决方案 »

  1.   

    第一个类
    [code=java]package com.lynn.operaingsystem1;
    import java.awt.BorderLayout;
    import com.lynn.operaingsystem1.*;
    import java.awt.FlowLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;
    import java.util.ArrayList;
    import java.util.List;import javax.swing.ComboBoxModel;
    import javax.swing.DefaultComboBoxModel;
    import javax.swing.JButton;
    import javax.swing.JComboBox;
    import javax.swing.JLabel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.JTextField;import javax.swing.SwingConstants;
    import javax.swing.WindowConstants;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.table.TableModel;
    import javax.swing.SwingUtilities;
    /**
    * This code was edited or generated using CloudGarden's Jigloo
    * SWT/Swing GUI Builder, which is free for non-commercial
    * use. If Jigloo is being used commercially (ie, by a corporation,
    * company or business for any purpose whatever) then you
    * should purchase a license for each developer using Jigloo.
    * Please visit www.cloudgarden.com for details.
    * Use of Jigloo implies acceptance of these licensing terms.
    * A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR
    * THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED
    * LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
    */
    public class ClientFrame extends javax.swing.JFrame {
    private JLabel jLabel1;
    private JLabel jLabel2;
    private JComboBox luXian;
    private JLabel jLabel3;
    private JLabel jLabel4;
    private JScrollPane jScrollPane1; private JButton buy;
    private JTextField piaoshu;
    private JComboBox banci;
    private JTable LXtable;
    private JButton LXselect;
    public List<Message> msg = new ArrayList<Message> ();
    private JButton jbConnect;
    private JButton exit;

    private Socket s = null;
    private DataOutputStream dos = null;
    private ObjectInputStream ois = null;
    /**
    * Auto-generated main method to display this JFrame
    */
    public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
    public void run() {
    ClientFrame inst = new ClientFrame();
    inst.setLocationRelativeTo(null);
    inst.setVisible(true);
    }
    });
    }

    public ClientFrame() {
    super();
    this.setTitle("网上购票系统--by lynn");
    connect();
    getNewMSG();
    initGUI();
    }

    public void getNewMSG() {
    msg.clear();
    try {
    for(int i = 0 ;i< 10 ;i++) {
    Message m = (Message)ois.readObject();
    msg.add(m);
    System.out.println(m);
    }
    } catch (ClassNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    private void connect() {
    try {
    s = new Socket("127.0.0.1", 8888);
    dos = new DataOutputStream(s.getOutputStream());
    ois = new ObjectInputStream(s.getInputStream());
    } catch (UnknownHostException e) {
    e.printStackTrace();
    } catch (IOException e) {
    e.printStackTrace();
    }
    } private void disConnect() {
    try {
    if(s!=null)s.close();
    if(dos!=null)dos.close();
    if(ois!=null)ois.close();
    } catch (IOException e1) {
    e1.printStackTrace();
    }
    }
    private void initGUI() {
    try {
    FlowLayout thisLayout = new FlowLayout();
    getContentPane().setLayout(thisLayout);
    setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
    {
    jLabel1 = new JLabel("网上购票系统", SwingConstants.CENTER);
    FlowLayout jLabel1Layout = new FlowLayout();
    jLabel1.setLayout(null);
    getContentPane().add(jLabel1);
    jLabel1.setText("\u7f51\u4e0a\u8d2d\u7968\u7cfb\u7edf");
    jLabel1.setFont(new java.awt.Font("微软雅黑",1,36));
    jLabel1.setPreferredSize(new java.awt.Dimension(366, 49));
    }
    {
    jLabel2 = new JLabel();
    getContentPane().add(jLabel2);
    jLabel2.setText("\u9009\u62e9\u8def\u7ebf :");
    jLabel2.setFont(new java.awt.Font("微软雅黑",0,14));
    jLabel2.setPreferredSize(new java.awt.Dimension(63, 26));
    }
    {
    ComboBoxModel luXianModel = 
    new DefaultComboBoxModel(
    new String[] { "广州--深圳", "深圳--广州","广州--江门","江门--广州" });
    luXian = new JComboBox();
    getContentPane().add(luXian);
    luXian.setModel(luXianModel);
    luXian.setPreferredSize(new java.awt.Dimension(105, 26));
    }
    {
    LXselect = new JButton();
    getContentPane().add(LXselect);
    LXselect.setText("\u67e5\u8be2");
    LXselect.setPreferredSize(new java.awt.Dimension(82, 27));
    LXselect.addActionListener(new LXSelectActionListener());
    }
    {
    jScrollPane1 = new JScrollPane();
    getContentPane().add(jScrollPane1);
    jScrollPane1.setPreferredSize(new java.awt.Dimension(396, 241));
    {
    TableModel LXtableModel = 
    new DefaultTableModel(
    tableDate(LuXian.GzSz),
    new String[] { "班次",  "时间", "剩票", "价格" });
    LXtable = new JTable();
    jScrollPane1.setViewportView(LXtable);
    JScrollPane jsp = new JScrollPane();

    LXtable.setModel(LXtableModel);
    LXtable.setPreferredSize(new java.awt.Dimension(393, 214));
    LXtable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
    LXtable.setDropMode(javax.swing.DropMode.INSERT_ROWS);
    LXtable.setEnabled(false);
    }
    }
    {
    jLabel3 = new JLabel();
    getContentPane().add(jLabel3);
    jLabel3.setText("\u9009\u62e9\u73ed\u6b21\uff1a");
    jLabel3.setFont(new java.awt.Font("微软雅黑",0,14));
    jLabel3.setPreferredSize(new java.awt.Dimension(74, 37));
    }
    {
    ComboBoxModel banciModel = 
    new DefaultComboBoxModel(
    new String[] { "1000", "1001","1002","1003" });
    banci = new JComboBox();
    getContentPane().add(banci);
    banci.setModel(banciModel);
    }
    {
    jLabel4 = new JLabel("", SwingConstants.CENTER);
    getContentPane().add(jLabel4);
    jLabel4.setText("\u7968\u6570\uff1a");
    jLabel4.setFont(new java.awt.Font("微软雅黑",0,14));
    jLabel4.setPreferredSize(new java.awt.Dimension(55, 19));
    }
    {
    piaoshu = new JTextField();
    getContentPane().add(piaoshu);
    piaoshu.setPreferredSize(new java.awt.Dimension(64, 24));
    }
    {
    buy = new JButton();
    getContentPane().add(buy);
    buy.setText("\u8d2d\u4e70");
    buy.setPreferredSize(new java.awt.Dimension(69, 24));
    buy.addActionListener(new BuyActionListener());
    }

    {
    jbConnect = new JButton();
    getContentPane().add(jbConnect);
    jbConnect.setText("连接");
    jbConnect.setPreferredSize(new java.awt.Dimension(66, 40));
    jbConnect.addActionListener(new ActionListener() {

    public void actionPerformed(ActionEvent e) {
    connect();

    }
    });
    }
    {
    exit = new JButton();
    getContentPane().add(exit);
    exit.setText("退出");
    exit.setPreferredSize(new java.awt.Dimension(66, 40));
    exit.addActionListener(new ActionListener() {

    public void actionPerformed(ActionEvent e) {
    disConnect();

    System.exit(1);
    }
    });
    }
    pack();
    this.setSize(413, 465);
    } catch (Exception e) {
        //add your error handling code here
    e.printStackTrace();
    }
    }
      

  2.   

    class BuyActionListener implements ActionListener { @Override
    public void actionPerformed(ActionEvent e) {
    //非数字检查未添加
    int yupiao = 0 ;

    String buyBanci = (String)banci.getSelectedItem() ;
    for(int i = 0 ;i<10 ; i++) {
    if( msg.get(i).getBcID() .equals(buyBanci)){
    yupiao = msg.get(i).getBcTicket();
    buyBanci = msg.get(i).getBcID();
    }
    }
    int buyTicket = 0;
    String text = piaoshu.getText() ;
    if(text == null ) {
    System.out.println("输如为空");
    return ;
    }
    else {
    buyTicket = new Integer(piaoshu.getText());
    }
    if(buyTicket <= yupiao ){
    try {
    dos.writeUTF(buyBanci+buyTicket);
    getNewMSG();
    System.out.println(buyBanci+buyTicket);
    } catch (IOException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
    }
    }

    updateTable();
    }

    }

    public void updateTable() {
    switch(luXian.getSelectedIndex()){
    case 0:TableModel LXtableModel = new DefaultTableModel(
    tableDate(LuXian.GzSz),
    new String[] { "班次",  "时间", "剩票", "价格" });
    LXtable.setModel(LXtableModel);

    ComboBoxModel banciModel = 
    new DefaultComboBoxModel(
    new String[] { "1000", "1001","1002","1003" });
    banci.setModel(banciModel);
    break;
    case 1:TableModel LXtableModel2 = new DefaultTableModel(
    tableDate(LuXian.SzGz),
    new String[] { "班次",  "时间", "剩票", "价格" });
    LXtable.setModel(LXtableModel2);
    ComboBoxModel banciModel2 = 
    new DefaultComboBoxModel(
    new String[] { "2000", "2001"});
    banci.setModel(banciModel2);
    break;
    case 2:TableModel LXtableModel3 = new DefaultTableModel(
    tableDate(LuXian.GzJm),
    new String[] { "班次",  "时间", "剩票", "价格" });
    LXtable.setModel(LXtableModel3);
    ComboBoxModel banciModel3 = 
    new DefaultComboBoxModel(
    new String[] { "3000", "3001"});
    banci.setModel(banciModel3);
    break;
    case 3:TableModel LXtableModel4 = new DefaultTableModel(
    tableDate(LuXian.JmGz),
    new String[] { "班次",  "时间", "剩票", "价格" });
    LXtable.setModel(LXtableModel4);
    ComboBoxModel banciModel4 = 
    new DefaultComboBoxModel(
    new String[] { "4000", "4001"});
    banci.setModel(banciModel4);
    break;

    }
    }
    class LXSelectActionListener implements ActionListener{ @Override
    public void actionPerformed(ActionEvent e) {
    updateTable();
    }
    }

    public String[][] tableDate(LuXian lx){
    if(msg.isEmpty()) return new String[][] { };;
    if(lx == LuXian.GzSz) {
    return new String[][] { 
    { msg.get(0).getBcID(),msg.get(0).getBcTime(),new Integer(msg.get(0).getBcTicket()).toString(),new Integer(msg.get(0).getBcPrice()).toString()},
    { msg.get(1).getBcID(),msg.get(1).getBcTime(),new Integer(msg.get(1).getBcTicket()).toString(),new Integer(msg.get(1).getBcPrice()).toString()},
    { msg.get(2).getBcID(),msg.get(2).getBcTime(),new Integer(msg.get(2).getBcTicket()).toString(),new Integer(msg.get(2).getBcPrice()).toString()},
    { msg.get(3).getBcID(),msg.get(3).getBcTime(),new Integer(msg.get(3).getBcTicket()).toString(),new Integer(msg.get(3).getBcPrice()).toString()} 
    };
    }else if(lx ==LuXian.SzGz){
    return new String[][] { 
    { msg.get(4).getBcID(),msg.get(4).getBcTime(),new Integer(msg.get(4).getBcTicket()).toString(),new Integer(msg.get(4).getBcPrice()).toString()},
    { msg.get(5).getBcID(),msg.get(5).getBcTime(),new Integer(msg.get(5).getBcTicket()).toString(),new Integer(msg.get(5).getBcPrice()).toString()}};
    }
    else if(lx ==LuXian.GzJm){
    return new String[][] { 
    { msg.get(6).getBcID(),msg.get(6).getBcTime(),new Integer(msg.get(6).getBcTicket()).toString(),new Integer(msg.get(6).getBcPrice()).toString()},
    { msg.get(7).getBcID(),msg.get(7).getBcTime(),new Integer(msg.get(7).getBcTicket()).toString(),new Integer(msg.get(7).getBcPrice()).toString()}};
    }
    else {
    return new String[][] { 
    { msg.get(8).getBcID(),msg.get(8).getBcTime(),new Integer(msg.get(8).getBcTicket()).toString(),new Integer(msg.get(8).getBcPrice()).toString()},
    { msg.get(9).getBcID(),msg.get(9).getBcTime(),new Integer(msg.get(9).getBcTicket()).toString(),new Integer(msg.get(9).getBcPrice()).toString()}};
    }
    }
    }
    [/code]第二个类
    package com.lynn.operaingsystem1;
    import java.io.DataInputStream;
    import java.io.EOFException;
    import java.io.IOException;
    import java.net.*;
    import java.util.ArrayList;
    import java.util.List;
    import java.io.ObjectOutputStream;import javax.swing.table.DefaultTableModel;
    import javax.swing.table.TableModel;public class Servers {
    ServerSocket ss = null;
    boolean started = false ;
    public List<Message> msg = new ArrayList<Message> ();

    public static void main(String[] args) {
    new Servers().start();
    }

    public void start() {
    msg.add(new Message("1000", "07:00", 35, 50, LuXian.GzSz));
    msg.add(new Message("1001", "08:00", 35, 50, LuXian.GzSz));
    msg.add(new Message("1002", "09:30", 35, 50, LuXian.GzSz));
    msg.add(new Message("1003", "11:40", 35, 40, LuXian.GzSz));
    msg.add(new Message("2000", "07:00", 35, 50, LuXian.SzGz));
    msg.add(new Message("2001", "08:00", 35, 50, LuXian.SzGz));
    msg.add(new Message("3000", "07:00", 35, 50, LuXian.GzJm));
    msg.add(new Message("3001", "08:00", 35, 50, LuXian.GzJm));
    msg.add(new Message("4000", "07:00", 35, 50, LuXian.JmGz));
    msg.add(new Message("4001", "08:00", 35, 50, LuXian.JmGz));

    try {
    ss = new ServerSocket(8888);
    started = true;
    } catch (BindException e) {
    System.out.println("端口使用中....");
    System.out.println("请关掉相关程序并重新运行服务器!");
    System.exit(0);
    } catch (IOException e) {
    e.printStackTrace();
    }

    try {

    while(started) {
    Socket s = ss.accept();
    Client c = new Client(s);
    System.out.println("a client connected!");
    new Thread(c).start();
    //dis.close();
    }
    } catch (IOException e) {
    e.printStackTrace();
    } finally {
    try {
    if(ss != null){
    ss.close();
    ss = null;
    }
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }

    class Client implements Runnable {

    private Socket s = null;
    private DataInputStream dis = null;
    private boolean bConnected = false;
    private ObjectOutputStream oos = null;

    public Client(Socket s) {
    this.s = s;
    try {
    oos = new ObjectOutputStream(s.getOutputStream());
    dis = new DataInputStream(s.getInputStream());
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    sendMSG();
    bConnected = true;
    }
    public void sendMSG() {
    try {

    for(int i = 0 ; i<10 ; i++) {
    oos.writeObject(msg.get(i));
    System.out.println(msg.get(i));
    }

    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    public void run() {
    try {
    while(bConnected) {
    String str = dis.readUTF();
    if(str.isEmpty()) continue;
    String bc = str.substring(0, 4);
    int buyT = new Integer(str.substring(4, str.length()));
    buyTicket(bc,buyT);
    sendMSG();

    }
    } catch (EOFException e) {
    System.out.println("Client closed!");
    } catch (IOException e) {
    e.printStackTrace();
    } finally {
    try {
    if(dis != null) dis.close();
    if(s != null) s.close();
    } catch (IOException e1) {
    e1.printStackTrace();
    }
    }
    }

    }

    public synchronized void buyTicket(String bbc, int buyTicket) {
    //非数字检查未添加
    int yupiao = 0 ;

    String buyBanci = bbc;
    for(int i = 0 ;i<10 ; i++) {
    if( msg.get(i).getBcID().equals(buyBanci) ){
    yupiao = msg.get(i).getBcTicket();
    yupiao = yupiao - buyTicket;
    msg.get(i).setBcTicket(yupiao);
    }
    }

    }}第三个类
    package com.lynn.operaingsystem1;import java.io.Serializable;
    public class Message implements Serializable{
    private String bcID;
    private String bcTime;
    private int bcPrice;
    private int bcTicket;
    private LuXian lx;

    public Message(String bcID, String bcTime, int bcPrice, int bcTicket, LuXian lx) {
    super();
    this.bcID = bcID;
    this.bcTime = bcTime;
    this.bcPrice = bcPrice;
    this.bcTicket = bcTicket;
    this.lx = lx;
    } public String toString() {
    return "班次" + this.getBcID() + "余票" + this.getBcTicket() + "\n" ;
    }
    public String getBcID() {
    return bcID;
    } public void setBcID(String bcID) {
    this.bcID = bcID;
    } public String getBcTime() {
    return bcTime;
    } public void setBcTime(String bcTime) {
    this.bcTime = bcTime;
    } public int getBcPrice() {
    return bcPrice;
    } public void setBcPrice(int bcPrice) {
    this.bcPrice = bcPrice;
    } public int getBcTicket() {
    return bcTicket;
    } public void setBcTicket(int bcTicket) {
    this.bcTicket = bcTicket;
    } public LuXian getLx() {
    return lx;
    } public void setLx(LuXian lx) {
    this.lx = lx;
    }


    }
      

  3.   

    收到的是旧数据那说明你发送的就是旧数据这个跟IO 没啥关系,你得看看你发送的数据是什么从这入手。纠结IO 你就是奔溃也找不出
      

  4.   

    写两个action。
    你们培训班不是都在学struts2吗?
    完成一个action之后再跳转,在执行一次查询,
    您的代码太多确实没看。
      

  5.   

    问题已解决,在writeobject() 之后要加上reset()方法 ~其原理其实还不是很懂~ 对我这种没有深入学习io包的懒虫~ 那条管是怎样底层的实现对我来说太黑暗了:一下是我的解决过程:
    当天晚上~重新理清了逻辑思路~没有发现错误~更加确定了是io的错误~ 做了几次针对行的debug 例如开了两条objectoutputstream ~  发现两条在使用过程中第一次发送接收数据都没问题的时候可以第二次的时候不行~ 怀疑了跟io 中 write 的flush 类似的问题~ 管中存有影响第二次传送的东西~ 再查一次api 发现objectoutputstream 类中有一个reset()方法 是重置的传出对象的~结合用objectoutputstream 传出的对象要 实现 序列化端口~所以在flush 后加上这个方法终于可以了~~第一次发帖~ 贴了一大段代码感觉好像发错了~ 但是但是说可能也不知道能不能说清楚, 不过还是谢谢各位解答啦~ ~ 
      

  6.   


    谢谢回复~已解决啦~八楼有解困过程~刚看视频学完se~ 准备学html-css-javaScript 、servlet-JSP~ 框架可能还晚一个月 才能遇到~~