使用UDP协议的套接字可以发送和接收数据包,通过发送和接收消息,可以实现相应的网络编程功能。例如,联机下棋时,本地用户下棋后,给对方发送一条消息,对方即可知道本地用户下棋了,并显示出下棋结果。需要注意的是,虽然在同一台电脑上编程运行,但我们需要将双方想象成在不同电脑上运行(事实上也是这样的),双方不能够直接调用对方的函数方法,而是永远通过发送和接收消息来实现交互。
以下将展示简单的利用套接字实现的局域网通信。
public class UDPServer extends JFrame {
//关于图形用户界面的代码省去
private static UDPServer instance;
public static UDPServer getInstance() {
if (instance==null) {
instance=new UDPServer();
}
return instance;
}
public static void main(String[] args) throws Exception {
UDPServer.getInstance().ds=new DatagramSocket(UDPServer.getInstance().serverPort);
new Thread() { //接收信息的线程
public void run() {
while(true) {
try {
byte[] buf=new byte[1000];
DatagramPacket packet=new DatagramPacket(buf,buf.length);
UDPServer.getInstance().ds.receive(packet);
String s=new String(buf,0,packet.getLength());
UDPServer.getInstance().log.append("Client: "+s+"\n");
UDPServer.getInstance().addClient(packet.getAddress(),packet.getPort()); //添加客户
System.out.println(packet.getAddress());
} catch(Exception e) {
System.out.println("Error!");
}
}
}
}.start();
}
ActionListener sendListener=new ActionListener() { //发送按钮上的监听器
@Override
public void actionPerformed(ActionEvent e) {
try {
line=message.getText();
log.append("Sending: "+line+"\n");
byte[] buf=line.getBytes();
DatagramPacket packet=new DatagramPacket(buf,buf.length,
ips.get(index-1),ports.get(index-1));
ds.send(packet);
message.setText("");
} catch (Exception e1) {
e1.printStackTrace();
}
}
};
ActionListener clientListener=new ActionListener() { //选择用户的监听器
@Override
public void actionPerformed(ActionEvent e) {
JComboBox cb=(JComboBox)e.getSource();
String str=(String)cb.getSelectedItem();
str=str.substring(str.length()-1);
index=Integer.valueOf(str);
}
};
public void addClient(InetAddress i,int p) { //添加用户
for(int j=0;j<ips.size();j++) {
if(ips.get(j)==i&&ports.get(j)==p)
return ;
}
int mark=ips.size()+1;
clients.addItem("Client "+mark);
ips.add(i);
ports.add(p);
}
}
public class UDPClient extends JFrame {
//图形用户界面的代码省去
private static UDPClient instance;
public static UDPClient getInstance() {
if (instance==null) {
instance = new UDPClient();
}
return instance;
}
private static DatagramSocket ds;
public static void main(String[] args) throws Exception {
UDPClient.getInstance().ds=new DatagramSocket(UDPClient.getInstance().clientPort); //初始化数据包套接字,绑定到8082端口
UDPClient.getInstance().initialize(); //初始化界面
new Thread() { //负责接收信息的线程
public void run() {
while(true) {
try {
byte[] buf=new byte[1000];
DatagramPacket packet=new DatagramPacket(buf,buf.length);
ds.receive(packet); //接收信息
String s=new String(buf,0,packet.getLength());
UDPClient.getInstance().log.append("Server: "+s+"\n"); //在日志上显示收到的信息
} catch(Exception e) {
System.out.println("Error!");
}
}
}
}.start();
}
ActionListener sendListener=new ActionListener() { //send按钮的监听器
@Override
public void actionPerformed(ActionEvent e) {
try {
line=message.getText(); //获取要发送的文本
log.append("Sending: "+line+"\n"); //日志中记录
byte[] buf=line.getBytes();
DatagramPacket packet=new DatagramPacket(buf,buf.length,InetAddress.getByName(serverIp),serverPort);
ds.send(packet); //发送文本
message.setText(""); //清空消息文本框,以便发送下一次消息
} catch (Exception e1) {
e1.printStackTrace();
}
}
};
}