这是我最近做的一个udp的聊天室,我的思路是每个客户端创建一个DatagramSocket(端口5555),在每个客户端开启时打开一个线程进行循环端口监听(Socket.receive)。然后在192.168.137.0~254的ip段进行循环发送空的数据包(就是在这里出了问题)。当客户端收到空的数据包时,将包内的发送方地址转为InetSocketAddress并保存到容量;当发送消息时,从里面读出InerSocketAddress  发送。
问题是我循环发送数据包后,自己会收到自己发给自己的包(我的ip:192.168.137.2),可是查看包的来源时总显示是从192.168.137.3~5中的某个发来的(也就是ip的最后一段+了1~3个数),在别的机器上开启这个程序我也会收到空的包,显示来源也是对方ip+1~3不固定。不知道是怎么回事。但特定给我发送消息时(也就是只给我发送一次消息,不是循环)显示正确,是对方的ip。困惑中求高手解答!
下面是我的源代码,写的不好,请帮帮忙:
package testChat;import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.util.Iterator;
import java.util.Vector;import javax.swing.JEditorPane;import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;/**
 * 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 ChatClient extends JFrame { private JEditorPane inputText;/*发消息用的输入框*/
private JEditorPane outputText;/*显示消息用的框(用的不专业,我知道)*/
private JScrollPane jScrollPaneC;/*主窗口的中间ScrollPane,放显示框*/
private JScrollPane jScrollPaneD;/*下部ScrollPane,放输入框*/
private JButton sent, reset, clr, newConnect;/*按钮*/
private JPanel p, p2;/*下部的两个panel  p放jSrollPane p2放按钮*/
private Action a;/*内部类 按钮监听类*/
private DatagramSocket s;
private DatagramPacket packet;
private String name;/*姓名*/
private Vector<InetSocketAddress> v;/*动态数组,保存InetSocketAddress*/
private int port = 5555;/*端口号*/
/**
 * 构造方法  
 * param n  姓名
 * */
ChatClient(String n) {
super("chat");

// 实例化动态数组和按钮监听类
{
v = new Vector<InetSocketAddress>();
this.name = n;
a = new Action(this);
}

// 实例化DatagramSocket
try {
s = new DatagramSocket(port);
} catch (SocketException e) {
outputText.setText(e.getMessage());
}
// 界面
this.setLayout(new BorderLayout());
{
jScrollPaneC = new JScrollPane();
outputText = new JEditorPane();
jScrollPaneC.setHorizontalScrollBar(null);
outputText.setEditable(false);
jScrollPaneC.setViewportView(outputText);
add(jScrollPaneC, BorderLayout.CENTER);
}
{
jScrollPaneD = new JScrollPane();
inputText = new JEditorPane();
inputText.setPreferredSize(new java.awt.Dimension(outputText
.getWidth(), 50));
jScrollPaneD.setHorizontalScrollBar(null);
jScrollPaneD.setViewportView(inputText);
}
{
sent = new JButton("发送");
sent.addActionListener(a);
}
{
reset = new JButton("取消");
reset.addActionListener(a);
}
{
clr = new JButton("清屏");
clr.addActionListener(a);
}
{
newConnect = new JButton("退出");
newConnect.addActionListener(a);
}
{
p2 = new JPanel();
p2.add(sent);
p2.add(reset);
p2.add(clr);
p2.add(newConnect); }
{
p = new JPanel();
p.setLayout(new BorderLayout());
add(p, BorderLayout.SOUTH);
p.add(jScrollPaneD, BorderLayout.CENTER);
p.add(p2, BorderLayout.SOUTH);
}
{
GetM getM = new GetM();
Thread t = new Thread(getM);
t.start();
}

// 循环发送空的消息      就是这里感觉有问题  大侠们帮帮忙
{
for (int i = 1; i < 255; i++) {
String ip = "192.168.137." + i;
byte[] buf = "".getBytes();
try {
packet = new DatagramPacket(buf, buf.length,
new InetSocketAddress("192.168.137."+i, port));
s.send(packet);
} catch (SocketException e1) {
outputText.setText(e1.getMessage());
} catch (IOException e1) {
outputText.setText(e1.getMessage());
}
}


// 循环发送完显示窗口
{
this.setUndecorated(true);
this.setVisible(true);
this.pack();
this.setSize(outputText.getWidth(), 300);
this.setLocationRelativeTo(null);
}
}
}// 在显示框加入新消息
void addText(String str) {
String str1 = outputText.getText() + str + "\n";
outputText.setText(str1);
}// 内部类   按钮监听
private class Action implements ActionListener {
ChatClient chatClient; Action(ChatClient chat) {
chatClient = chat;
} public void actionPerformed(ActionEvent e) {
// 发送消息
if (e.getActionCommand().equals("发送")) {
if (inputText.getText().equals("")) {
JOptionPane.showMessageDialog(null, "请输入内容!");
} else {
byte[] buf = (name + ":" + inputText.getText()).getBytes();
Iterator<InetSocketAddress> iterator = v.iterator();

// while循环向vector中的地址发送消息
// 这里可以将while和下面一个大括号注释掉  
// 将(InetSocketAddress)iterator.next()写成new InetSocketAddress("192.168.137.2",port)我的地址  特定发送消息给我
while (iterator.hasNext()) {
try {
packet = new DatagramPacket(buf, buf.length,
(InetSocketAddress)iterator.next());
} catch (SocketException e1) {
outputText.setText(e1.getMessage());
}
try {
s.send(packet);
} catch (IOException e1) {
outputText.setText(e1.getMessage());
}
}
}
inputText.setText("");
// 其他
} else if (e.getActionCommand().equals("取消")) {
inputText.setText("");
} else if (e.getActionCommand().equals("清屏")) {
outputText.setText("");
} else if (e.getActionCommand().equals("退出")) {
chatClient.dispose();
System.exit(DISPOSE_ON_CLOSE);
} } }// 内部类  接收消息的线程
private class GetM implements Runnable {
public void run() {
byte[] buf;
while (true) {
try {
buf = new byte[2048];
packet = new DatagramPacket(buf, buf.length);
s.receive(packet);
String str = new String(packet.getData(), 0, packet.getLength());//                                 这里是显示发送来的消息源的地址    循环发送得到的地址用这两种方法显示的不一样哦
// 为什么 但是特定发送给消息会看到一样的源ip  
System.out.println(str + "    " + packet.getSocketAddress()+ "    "+packet.getAddress());

// 如果消息为空  保存消息源 地址类
if (str.equals("")||str==null) {
 v.add((InetSocketAddress) packet.getSocketAddress());
 } else {
addText(str);
 }
} catch (IOException e) {
outputText.setText(e.getMessage());
} }
} }

//主方法
public static void main(String[] args) { new ChatClient("YX");
}
}表达的不是很清楚,总之有能力的高手帮忙看看。不要告我有别的类可以做到这个,比如MulticastSocket  我就想知道我这个问题出在哪
谢谢各位大侠