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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 陈淑飞 于 2012-8-1 15:50 编辑

小测试代码,目的是发送端从键盘中,输入字符。接收端接到字符后转成大写。当发送端发"over"时,接受端接到打开并结束,关闭流掉。
但测试代码存在问题,while循环停不了。下面是代码:
代码一: while循环用 类静态变量FLAG控制:
  1. import java.net.*;
  2. import java.io.*;
  3. import java.util.Date;
  4. public class UdpSocketTest{
  5. public static boolean FLAG = true ;
  6. public static void main(String[] args){

  7. }
  8. }

  9. class SerSocket{
  10. public static void main(String[] args) throws Exception{
  11. DatagramSocket ds = new DatagramSocket(40009);
  12. while(UdpSocketTest.FLAG)
  13. {
  14. byte[] buf = new byte[1024];
  15. DatagramPacket dp = new DatagramPacket(buf,buf.length);
  16. ds.receive(dp);
  17. InetAddress ia = dp.getAddress();
  18. String ip = ia.getHostAddress();
  19. System.out.println(ip+"..... connected");
  20. String content = new String(dp.getData(),0,dp.getLength());
  21. content = content.toUpperCase();
  22. System.out.println("content=="+content);
  23. Thread.sleep(5000); //先暂停5秒,等if over先执行,置FLAG为false
  24. Date d = new Date();
  25. System.out.println(d.toString()+"Ser执行UdpSocketTest.FLAG==::"+UdpSocketTest.FLAG);
  26. }
  27. ds.close();
  28. }

  29. }

  30. class CliSocket{

  31. public static void main(String[] args) throws Exception{

  32. DatagramSocket ds = new DatagramSocket();
  33. InetAddress ia = InetAddress.getByName("127.0.0.1");
  34. BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  35. String line = null;
  36. while((line=br.readLine())!=null){
  37. byte[] buf = line.getBytes();
  38. DatagramPacket dp = new DatagramPacket(buf,buf.length,ia,40009);
  39. ds.send(dp);
  40. if("over".equals(line))
  41. {
  42. UdpSocketTest.FLAG = false;
  43. Date d = new Date();
  44. System.out.println(d.toString()+"Cli执行UdpSocketTest.FLAG==::"+UdpSocketTest.FLAG);
  45. break ;
  46. }
  47. }
  48. ds.close();
  49. br.close();

  50. }
  51. }
复制代码
代码二: while循环用 单例 Flag成员变量  控制:
  1. import java.net.*;
  2. import java.io.*;
  3. import java.util.Date;
  4. public class UdpSocketTest2{
  5. //public static boolean FLAG = true ;
  6. private static final UdpSocketTest2 ut = new UdpSocketTest2(); //郁闷,换成单例类,还是一样存在问题。
  7. private boolean flag = true ;
  8. private UdpSocketTest2(){
  9. }
  10. public static UdpSocketTest2 getInstance(){
  11. return ut ;
  12. }
  13. public void setFlag(boolean flag){
  14. this.flag = flag;
  15. }
  16. public boolean getFlag(){
  17. return flag ;
  18. }

  19. public static void main(String[] args){

  20. }
  21. }

  22. class SerSocket{
  23. public static void main(String[] args) throws Exception{
  24. DatagramSocket ds = new DatagramSocket(40009);
  25. UdpSocketTest2 ut = UdpSocketTest2.getInstance();
  26. while(ut.getFlag())
  27. {
  28. byte[] buf = new byte[1024];
  29. DatagramPacket dp = new DatagramPacket(buf,buf.length);
  30. ds.receive(dp);
  31. InetAddress ia = dp.getAddress();
  32. String ip = ia.getHostAddress();
  33. System.out.println(ip+"..... connected");
  34. String content = new String(dp.getData(),0,dp.getLength());
  35. content = content.toUpperCase();
  36. System.out.println("content=="+content);
  37. Thread.sleep(5000); //先暂停5秒,等if over先执行,置FLAG为false
  38. Date d = new Date();
  39. System.out.println(d.toString()+"Ser 执行ut.getFlag()==::"+ut.getFlag());
  40. }
  41. ds.close();
  42. }

  43. }

  44. class CliSocket{

  45. public static void main(String[] args) throws Exception{
  46. UdpSocketTest2 ut = UdpSocketTest2.getInstance();
  47. DatagramSocket ds = new DatagramSocket();
  48. InetAddress ia = InetAddress.getByName("127.0.0.1");
  49. BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  50. String line = null;
  51. while((line=br.readLine())!=null){
  52. byte[] buf = line.getBytes();
  53. DatagramPacket dp = new DatagramPacket(buf,buf.length,ia,40009);
  54. ds.send(dp);
  55. if("over".equals(line))
  56. {
  57. ut.setFlag(false);
  58. Date d = new Date();
  59. System.out.println(d.toString()+"Cli 执行ut.getFlag()==::"+ut.getFlag());
  60. break ;
  61. }
  62. }
  63. ds.close();
  64. br.close();

  65. }
  66. }
复制代码
Why?为什么循环停不了,测试结果如图:



图上,显示证明了,FLAG已经被置为flase了,为什么5秒后打印却是true呢?
用单例模式也是一样的,求解?
----
ps: 不要说在接收端也弄个over的判断,再break循环。 我就想知道,为什么以上两种方式的while循环结束不了,为什么5秒前FLAG为false,5秒后为true了。

------------
问题解决,结贴。

评分

参与人数 1技术分 +1 收起 理由
田建 + 1 赞一个!

查看全部评分

3 个回复

倒序浏览

回帖奖励 +10

//楼主,这两段代码我都给你修改了一下,你看我的注释吧。。。。。。。。。。
//发送代码,这个发送代码你写一个类,类名叫CliSocket
import java.net.*;
import java.io.*;
import java.util.Date;
//这里去掉public,去掉类中的main方法,
class UdpSocketTest{
public static boolean FLAG = true ;

}
//这里加上public这个为主类,。。。。。。。。。。。注意这时这个flag为true,
public class CliSocket{

public static void main(String[] args) throws Exception{

DatagramSocket ds = new DatagramSocket();
InetAddress ia = InetAddress.getByName("127.0.0.1");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while((line=br.readLine())!=null){
byte[] buf = line.getBytes();
DatagramPacket dp = new DatagramPacket(buf,buf.length,ia,40009);
ds.send(dp);
//这里直到你输入一个over字符串才把flag赋值成false,但是一定注意这里是发送类中的flag,与另一个类SerSocket中的flag毫无关系和联系
if("over".equals(line))
{
UdpSocketTest.FLAG = false;
Date d = new Date();
System.out.println(d.toString()+"Cli执行UdpSocketTest.FLAG==::"+UdpSocketTest.FLAG);
break ;
}
}
ds.close();
br.close();

}
}




//接受代码写成一个类,类名称叫SerSocket

import java.net.*;
import java.io.*;
import java.util.Date;
//这里去掉public,去掉类中的main方法,

class UdpSocketTest{
public static boolean FLAG = true ;

}
//这里加上public这个为主类,注意这时这个flag为true,你这里之所以一直循环,就是因为这个flag一直为true,你并没有在这个SerSocket中赋值,我给你加了一些代码,你看

public class SerSocket{
public static void main(String[] args) throws Exception{
DatagramSocket ds = new DatagramSocket(40009);
while(UdpSocketTest.FLAG)
{
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
ds.receive(dp);
InetAddress ia = dp.getAddress();
String ip = ia.getHostAddress();
System.out.println(ip+"..... connected");
String content = new String(dp.getData(),0,dp.getLength());
content = content.toUpperCase();

//这是我给你添加的代码你看看。。。。。。。。。。。。。。。。。。。
if("over".equals(content) || "OVER".equals(content)){
UdpSocketTest.FLAG = false;
}

System.out.println("content=="+content);
Thread.sleep(5000); //先暂停5秒,等if over先执行,置FLAG为false
Date d = new Date();
System.out.println(d.toString()+"Ser执行UdpSocketTest.FLAG==::"+UdpSocketTest.FLAG);
}
ds.close();
}

}

11111111111111.jpg (112.55 KB, 下载次数: 20)

增加代码前

增加代码前

222222222222222222.jpg (103.3 KB, 下载次数: 20)

修改后的执行

修改后的执行
回复 使用道具 举报
{:soso_e100:},我已经帮你解决了,给我点分数啊,怎么样,我正在上班,抽时间给你看的,你满意吗?补充,一个类叫CliSocket.java,一个叫SerSocket.java
{:soso_e181:}

点评

好似,给不了技术分了,只能多给点钱了。呵呵,加油。哥们。  发表于 2012-8-1 16:06

评分

参与人数 1黑马币 +10 收起 理由
陈淑飞 + 10 嗯 ,没仔细看哦,呵呵,你答的也是这个意.

查看全部评分

回复 使用道具 举报
龙卷风V龙卷风 发表于 2012-8-1 15:19
,我已经帮你解决了,给我点分数啊,怎么样,我正在上班,抽时间给你看的,你满意吗?补充, ...
ps: 不要说在接收端也弄个over的判断,再break循环。 我就想知道,为什么以上两种方式的while循环结束不了,为什么5秒前FLAG为false,5秒后为true了


抱歉,给不了你。你的说法,我不太认可。我并不想在接收端,弄个over这样的判断。再来结束掉while循环。
这题目,我自己已经解决了。

原因:接收端与发送端都是main函数,我启动了两个命令窗口两个java,即产生了两个JVM。
两个JVM之间,数据并不是共享的。两个JVM中 UdpSocketTest.FLAG都是独立的。

在接收端main中,我并没有改变UdpSocketTest.FLAG的值,所以无论在发送端做何动作,不修改接收端代码。UdpSocketTest.FLAG永远不可以为false。
所以与UDP发包接包,根本没有关系的。

至少目前我的电脑配置及环境搭配,还不支持 云服务或集群服务。
为了证明,以上说明。特此发个简单测试代码:

import java.util.Date;
class DataTest{
        public static int d1 = 1;

}


class JVM2{
        public static void main(String[] args) throws Exception{
               
                DataTest.d1 = 2 + DataTest.d1;
                System.out.println("JVM2停止5秒再打印 DataTest.d1="+DataTest.d1);
                Thread.sleep(5000);
                Date d = new Date();
                System.out.println(d+"  JVM2-------::"+DataTest.d1);
        }

}

class JVM1{

        public static void main(String[] args){
                DataTest.d1 = 3 + DataTest.d1;
                Date d = new Date();
                System.out.println(d+"  JVM1-------::"+DataTest.d1);
        }
}

--------
先运行 JVM2,d1值为3,此时立马运行JVM1,d1的值,不为因为JVM2中值为3了,再加3.而是4.


OVER,结题。
呵呵,自己动手解决,丰衣足食。:D
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马