// サーバープログラム
import java.io.*;
import java.util.*;
import java.net.*;
class UserInfo {
};
public class ChatSv {
byte[] buf = new byte[ChatParam.MSIZE];
UserInfo[] users = new UserInfo[ChatParam.MAX_USERS];
/* ある参加者からメッセージが送信されてきたら、それ以外の参加者にそのメッセージを転送する */
class UserProcess
extends Thread {
UserInfo userInfo;
UserProcess(UserInfo userInfo){
this.userInfo = userInfo;
}
public void run() {
try {
while(true){
if (userInfo.sock != null) {
int count = userInfo.is.read(buf);
if (count > 0) {
sendAll
(makeMessage
(ChatParam.
MSG,
new String(buf
))); }
}
}
/* 誰かが抜けた(接続が切れた)場合には他の参加者に抜けたことを伝える */
sendAll(makeMessage(ChatParam.LEAVE, userInfo.name + "さんが抜けました"));
}
try {
userInfo.sock.close();
userInfo.sock = null;
}
}
}
public static void main
(String[] args
) { try{
new ChatSv().start();
}
}
for (int i = 0; i < ChatParam.MAX_USERS; i++) {
users[i] = new UserInfo();
users[i].sock = null;
};
// このループの仕事は接続受付だけにする
while (true) {
try {
/* クライアントからの接続待ち準備 */
asock = ssock.accept();
/* クライアントからの接続受け付け */
UserInfo newUser = addUser(asock);
if (newUser != null) {
/* 接続してきたクライアントに参加OKを伝える */
newUser.os.write(makeMessage(ChatParam.MSG, "チャットに参加しました"));
new UserProcess(newUser).start();
/* すでに参加しているクライアントに新しい参加者を伝える */
sendAll(makeMessage(ChatParam.JOIN, newUser.name + "さんが加わりました"));
} else {
/* すでに最大人数に達しているので参加不可をクライアントに伝えて切断処理を行う */
asock.getOutputStream().write(makeMessage(ChatParam.FULL, "最大人数に達しているため参加できませんでした"));
asock.close();
}
// 少なくともこれ以降のクライアントとの通信は並列に行う必要あり
// (新たな参加者受け付けと参加済みのクライアントからのメッセージ
// 受信は順序が決まっていないため)
Thread.
currentThread().
sleep(100);
e.printStackTrace();
}
}
/* 通信終了処理(上が無限ループなので意味はないが) */
// ssock.close();
}
public synchronized byte[] makeMessage
(byte param,
String message
) { byte[] result = new byte[ChatParam.MSIZE];
byte[] messageBytes = (message+"\0").getBytes();
result[0] = param;
System.
arraycopy(messageBytes,
0, result,
1,
(messageBytes.
length < ChatParam.
MSIZE-1 ) ? messageBytes.
length : ChatParam.
MSIZE-1); return result;
}
for (int i = 0; i < ChatParam.MAX_USERS; i++) {
if (users[i].sock == null) {
// まだ最大人数に達していないので参加OK
users[i].sock = s;
users[i].is = s.getInputStream();
users[i].os = s.getOutputStream();
users[i].is.read(buf);
users
[i
].
name = new String(buf,
1, ChatParam.
NSIZE).
trim(); return users[i];
}
}
return null;
}
public synchronized void sendAll (byte[] message) {
if (message == null) {
return;
}
for (int i = 0; i < ChatParam.MAX_USERS; i++) {
if (users[i].sock != null) {
try {
users[i].os.write(message);
}
}
}
}
}