A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Simple_love 中级黑马   /  2013-10-22 09:37  /  1217 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 Simple_love 于 2013-10-27 22:56 编辑

在网络编程中使用readUTF()等操作输入输出流时容易产生阻塞。比如写一个聊天的程序,只能一边说一句,另一边接收完程序才能往下执行。这要如何解决?有没有聊天程序两边可以任意输入的源代码给个?
public class chatClient extends Frame {
/*** @param args*/
TextField tfTxT=new TextField();
TextArea taContent=new TextArea();
Socket s=null;DataOutputStream dos=null;
DataInputStream dis=null;

    private boolean bConnected =false;
public static void main(String[] args) {
new chatClient().lunachFrame();
}
  private class RecvThread() implements Runnable{
public void run() {
try{
while(bConnected){
String str=dis.read()UTF();
taContent.setText(taContent.getText()+str+'\n');
}
}catch(IOException e){
e.printStackTrace();
}
   }
}
public void lunachFrame(){
this.setLocation(400, 300);
this.setSize(300,300);
//this.setLayout(new FlowLayout());
this.add(tfTxT,"South");
this.add(taContent,"North");
pack();
tfTxT.addActionListener(new TFListener());
this.addWindowListener(new WindowClose());
this.setVisible(true);connect()();
new Thread()(new RecvThread()).start();
   }
public void connect()(){
try {s= new Socket("127.0.0.1",8888);
dos =new DataOutputStream(s.getOutputStream());
dis =new DataInputStream(s.getInputStream());
System.out.println("connect()ed!");
bConnected=true;
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
   }
}
public void disconnect(){
try {
dos.close();s.close();
} catch (Exception e) {
// TODO 自动生成 catch 块
e.printStackTrace();
}
   class WindowClose extends WindowAdapter{
@Override
public void windowClosing(WindowEvent e) {
// TODO 自动生成方法存根
System.exit(0);disconnect();
   }
    }
private class TFListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
String str=tfTxT.getText().trim();
//trim去掉两边空格//
taContent.setText(str);tfTxT.setText("");
try {
dos.writeUTF(str);
dos.flush();
//dos.close();
} catch (IOException e1) {
e1.printStackTrace();
  }
  }
}
}


评分

参与人数 1技术分 +1 收起 理由
李江 + 1 很给力! 代码规范哦

查看全部评分

2 个回复

倒序浏览
楼主你好,如果问题已解决请将帖子状态修改为提问结束,

如果未解决请继续提问,谢谢合作

修改方法请看解释帖:http://bbs.itheima.com/thread-89313-1-1.html
回复 使用道具 举报
哥么你这问题要说清楚需要一点时间,大方向我可以告诉你,用多线程

可以采用经典的c/s模式,一个服务器为多个客户端服务,当一个客户端请求服务时,便开启一个新的线程为之服务

你说的明显是采用顺序结构写的代码,一边发完了消息,后面的代码中有阻塞时方法,非要等到接收到对方发来的消息,你才能再次发消息

我写了个简易的程序,先解决你得疑惑
  1. 服务端代码
  2. import java.net.*;
  3. import java.io.*;
  4. public class Server1 implements Runnable
  5. {
  6.     ServerSocket server = null;
  7.     Socket clientSocket;
  8.     boolean flag = true;                 //标记是否结束
  9.     Thread c;                            //向客户器端发送信息的线程
  10.     BufferedReader sin;
  11.     DataOutputStream sout;
  12.     public static void main(String args[])
  13.     {
  14.         new Server1().ServerStart();
  15.     }
  16.     public void ServerStart()
  17.     {
  18.         try
  19.         {
  20.             server = new ServerSocket(5678);
  21.             System.out.println("端口号:"+server.getLocalPort());
  22.             while(flag)
  23.             {
  24.                 clientSocket = server.accept();
  25.                 System.out.println("已建立连接!");
  26.                 InputStream is = clientSocket.getInputStream();
  27.                 sin = new BufferedReader(new InputStreamReader(is));
  28.                 OutputStream os = clientSocket.getOutputStream();
  29.                 sout = new DataOutputStream(os);
  30.                 c = new Thread(this);
  31.                 c.start();               //启动线程,向客户器端发送信息
  32.                 String aline;
  33.                 while((aline=sin.readLine())!=null)
  34.                 {                        //接收客户端的数据
  35.                      System.out.println(aline);
  36.                      if(aline.equals("bye"))
  37.                      {
  38.                          flag = false;
  39.                          c.interrupt();  //线程中断
  40.                          break;
  41.                      }
  42.                 }       
  43.                 sout.close();            //关闭流
  44.                 os.close();
  45.                 sin.close();
  46.                 is.close();
  47.                 //clientSocket.close();         //关闭Socket连接
  48.                 System.exit(0);          //程序运行结束
  49.             }
  50.         }
  51.         catch(Exception e)
  52.         {
  53.             System.out.println(e);
  54.         }
  55.     }
  56.     public void run()
  57.     {
  58.         while(true)
  59.         {
  60.             try
  61.             {
  62.                 int ch;
  63.                 while((ch=System.in.read())!=-1)
  64.                 {                        //从键盘接收字符并向客户端发送
  65.                     sout.write((byte)ch);
  66.                     if(ch=='\n')
  67.                         sout.flush();    //将缓冲区内容向输出流发送
  68.                 }
  69.             }
  70.             catch(Exception e)
  71.             {
  72.                 System.out.println(e);
  73.             }
  74.         }
  75.     }
  76.     public void finalize()               //析构方法
  77.     {
  78.         try
  79.         {
  80.             server.close();              //停止ServerSocket服务
  81.         }
  82.         catch(IOException e)
  83.         {
  84.             System.out.println(e);
  85.         }
  86.     }
  87. }
复制代码
  1. 客户端代码
  2. import java.net.*;
  3. import java.io.*;
  4. public class Client1 implements Runnable
  5. {
  6.     Socket clientSocket;
  7.     boolean flag=true;                   //标记是否结束
  8.     Thread c;                            //用于向服务器端发送信息
  9.     BufferedReader cin;
  10.     DataOutputStream cout;
  11.     public static void main(String arg[])
  12.     {
  13.         new Client1().ClientStart();
  14.     }
  15.     public void ClientStart()
  16.     {
  17.         try
  18.         {                                //连接服务器端,这里使用本机
  19.             clientSocket=new Socket("localhost",5678);
  20.             System.out.println("已建立连接!");
  21.             while(flag)
  22.             {                            //获取流对象
  23.                 InputStream is = clientSocket.getInputStream();
  24.                 cin=new BufferedReader(new InputStreamReader(is));
  25.                 OutputStream os = clientSocket.getOutputStream();
  26.                 cout = new DataOutputStream(os);
  27.                 c = new Thread(this);
  28.                 c.start();               //启动线程,向服务器端发送信息
  29.                 String aline;
  30.                 while((aline=cin.readLine())!=null)
  31.                 {                        //接收服务器端的数据
  32.                     System.out.println(aline);
  33.                     if(aline.equals("bye"))
  34.                     {
  35.                         flag = false;
  36.                         c.interrupt();
  37.                         break;
  38.                     }
  39.                 }       
  40.                 cout.close();
  41.                 os.close();
  42.                 cin.close();
  43.                 is.close();
  44.                 clientSocket.close();    //关闭Socket连接
  45.                 System.exit(0);         
  46.             }
  47.         }
  48.         catch(Exception e)
  49.         {
  50.             System.out.println(e);
  51.         }
  52.     }
  53.     public void run()
  54.     {
  55.         while(true)
  56.         {
  57.             try
  58.             {                            //从键盘接收字符并向服务器端发送
  59.                 int ch;
  60.                 while((ch=System.in.read())!=-1)
  61.                 {
  62.                     cout.write((byte)ch);
  63.                     if(ch=='\n')
  64.                         cout.flush();    //将缓冲区内容向输出流发送
  65.                 }
  66.             }
  67.             catch(Exception e)
  68.             {
  69.                 System.out.println(e);
  70.             }
  71.         }
  72.     }
  73. }
复制代码
怎么运行不需要我教你吧,控制台哦

好好学习,不懂得可以问我

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马