[java]UDPベースのSocket通信Demo
27797 ワード
JAva授業のプログラミング作業:先生からのdemoに基づいてクライアントがサーバ側にデータを送信し、サーバ側がクライアントを受け入れてデータ放送を行うことを実現する.
全体の機能はチャットルームに似ていて、コード部分はあまり難しくありませんが、本機のテストでこのような問題が発生しました.
サービス側は,各SocketクライアントのIPをSetセットに格納することで,データを受け取るたびに現在のすべてのIPに転送する.しかし、本機のプレゼンテーションの時に開いているすべてのChatClientクライアントは同じIPで、どのようにテストしますか?
解決策は,本機のテスト時にサービス側が複数の異なるポートに転送すればよいということであり,このように走り出したクライアントは異なるポートで傍受を行う(ブロードキャストを実現するためだけに,実際のアプリケーションではIPで転送する).
クライアントコード:
サービス側コード:
全体の機能はチャットルームに似ていて、コード部分はあまり難しくありませんが、本機のテストでこのような問題が発生しました.
サービス側は,各SocketクライアントのIPをSetセットに格納することで,データを受け取るたびに現在のすべてのIPに転送する.しかし、本機のプレゼンテーションの時に開いているすべてのChatClientクライアントは同じIPで、どのようにテストしますか?
解決策は,本機のテスト時にサービス側が複数の異なるポートに転送すればよいということであり,このように走り出したクライアントは異なるポートで傍受を行う(ブロードキャストを実現するためだけに,実際のアプリケーションではIPで転送する).
クライアントコード:
import javax.print.attribute.HashPrintServiceAttributeSet;
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.*;
public class ChatClient extends JFrame {
JTextArea contents = new JTextArea();
JLabel label1 = new JLabel(" ");
JTextField address = new JTextField();
JLabel label2 = new JLabel(" ");
JTextField username = new JTextField();
JButton online = new JButton(" ");
JButton offline = new JButton(" ");
JTextField input = new JTextField();
JButton send = new JButton(" ");
boolean onlineFlag = false;
public ChatClient() {
super("Chat Client");
contents.setEditable(false);
getContentPane().add(contents);
JPanel p1 = new JPanel();
p1.setLayout(new FlowLayout(FlowLayout.LEADING));
address.setPreferredSize(new Dimension(100, 28));
username.setPreferredSize(new Dimension(80, 28));
input.setPreferredSize(new Dimension(180, 28));
p1.add(label1);
p1.add(address);
p1.add(label2);
p1.add(username);
p1.add(online);
p1.add(offline);
p1.add(input);
p1.add(send);
offline.setEnabled(false);
send.setEnabled(false);
getContentPane().add(p1, BorderLayout.SOUTH);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
onlineFlag = false;
Map<String, Object> m1 = new HashMap<String, Object>();
m1.put("time", new Date()); //
m1.put("username", getUsername());
m1.put("onlineFlag", onlineFlag);
send(getServerAddress(), 2222, m1);
System.exit(0);
}
});
ActionListener al = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
String server = getServerAddress();
if (server == null || server.length() == 0) {
JOptionPane.showMessageDialog(ChatClient.this, " !");
return;
}
if (ae.getSource() == online) {
//
if (!onlineFlag) {
onlineFlag = true;
Map<String, Object> m1 = new HashMap<String, Object>();
m1.put("time", new Date()); //
m1.put("username", getUsername());
m1.put("onlineFlag", onlineFlag);
online.setEnabled(false);
offline.setEnabled(true);
send.setEnabled(true);
address.setEnabled(false);
username.setEnabled(false);
send(getServerAddress(), 2222, m1);
}
} else {
//
if (onlineFlag) {
onlineFlag = false;
Map<String, Object> m1 = new HashMap<String, Object>();
m1.put("time", new Date()); //
m1.put("username", getUsername());
m1.put("onlineFlag", onlineFlag);
online.setEnabled(true);
offline.setEnabled(false);
send.setEnabled(false);
address.setEnabled(true);
username.setEnabled(true);
send(getServerAddress(), 2222, m1);
}
}
}
};
ActionListener al2 = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
Map<String, Object> m1 = new HashMap<String, Object>();
m1.put("time", new Date());
m1.put("username", getUsername());
m1.put("input", getInput());
send(getServerAddress(), 2222, m1);
}
};
send.addActionListener(al2);
online.addActionListener(al);
offline.addActionListener(al);
// setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(720, 400);
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
setLocation((d.width - 720) / 2, (d.height - 400) / 2);
setVisible(true);
new Thread() {
public void run() {
try {
// 2221 , , 。
DatagramSocket rSocket = new DatagramSocket(2220);
while (true) {
byte[] buffer = new byte[1024 * 16];
DatagramPacket recvPacket = new DatagramPacket(buffer, buffer.length);
rSocket.receive(recvPacket);
byte[] data = recvPacket.getData();
byte[] recvData = new byte[recvPacket.getLength()];
System.arraycopy(buffer, 0, recvData, 0, recvData.length);
// Map
Map<String, Object> map = convertByteArrayToMap(recvData);
if (map.containsKey("onlineFlag")) { //
boolean b = (boolean) map.get("onlineFlag");
if (b) { //
map.put("input", " ");
} else { //
map.put("input", " ");
}
}
Date time = (Date) map.get("time");
String s = convertDateToFormatString(time);
String user = (String) map.get("username");
user = "[" + user + "]";
contents.append(s + user + ": " + (String) map.get("input") + "\r
");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
public String getServerAddress() {
String s = address.getText();
//trim
s = s.trim();
return s;
}
public String getUsername() {
String s = username.getText();
s = s.trim();
if (s == null || s.length() == 0) {
s = " ";
}
return s;
}
public String getInput() {
String s = input.getText();
s = s.trim();
if (s == null || s.length() == 0) {
s = " ";
}
return s;
}
public static String convertDateToFormatString(Date d) {
return new java.text.SimpleDateFormat("(yyyy-MM-dd HH:mm:ss)").format(d);
}
public static void send(String ip, int port, Map<String, Object> map) {
try {
byte[] data = convertMapToByteArray(map);
DatagramSocket socket = new DatagramSocket();
DatagramPacket packet = new DatagramPacket(data, data.length);
packet.setSocketAddress(new InetSocketAddress(ip, port));
socket.send(packet);
} catch (Exception e) {
e.printStackTrace();
}
}
public static byte[] convertMapToByteArray(Map<String, Object> map) {
try {
// , map
ByteArrayOutputStream b = new ByteArrayOutputStream();
ObjectOutputStream ois = new ObjectOutputStream(b);
ois.writeObject(map);
byte[] temp = b.toByteArray();
return temp;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static Map<String, Object> convertByteArrayToMap(byte[] data) {
try {
ByteArrayInputStream bais = new ByteArrayInputStream(data);
ObjectInputStream ois = new ObjectInputStream(bais);
Map<String, Object> result = (Map<String, Object>) ois.readObject();
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
new ChatClient();
}
}
サービス側コード:
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;
public class ChatServer {
LinkedBlockingQueue<Map<String, Object>> queue = new LinkedBlockingQueue<Map<String, Object>>();
Set<String> onlineIPs = new HashSet<String>(); // IP。
public ChatServer() {
try {
new Thread() {
public void run() {
while (true) {
try {
// , , IP , IP
if( !queue.isEmpty() ){
if( !onlineIPs.isEmpty() ){
for(String ip : onlineIPs){
// , 2220
ChatClient.send(ip, 2221, queue.peek() );
ChatClient.send(ip, 2220, queue.remove() );
}
}
}
//end
} catch (Exception e) {
e.printStackTrace();
}
}
}
}.start();
// 2222
DatagramSocket serverSocket = new DatagramSocket(2222);
System.out.println("Chat Server started.");
while (true) {
byte[] buffer = new byte[1024 * 16];
DatagramPacket recvPacket = new DatagramPacket(buffer, buffer.length);
serverSocket.receive(recvPacket);
InetSocketAddress remoteAddress = new InetSocketAddress(recvPacket.getAddress(),
recvPacket.getPort());
System.out.println(" " + remoteAddress.getHostString() + " ");
byte[] data = recvPacket.getData();
byte[] recvData = new byte[recvPacket.getLength()];
System.arraycopy(buffer, 0, recvData, 0, recvData.length);
System.out.println(recvData.length);
Map<String, Object> map = ChatClient.convertByteArrayToMap(recvData);
System.out.print("map "+map.size());
if (map.containsKey("onlineFlag")) { //
boolean b = (boolean) map.get("onlineFlag");
if (b) { //
onlineIPs.add(remoteAddress.getHostString());
} else { //
onlineIPs.remove(remoteAddress.getHostString());
}
}
queue.add(map);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new ChatServer();
}
}