📄 simpserver.java
字号:
/**
* <p>Title: Learning material for socket programming</p>
* <p>Description: SIMP: Simple Instant Message Protocol. SIMP server records who is online, and redirects
* messages to the correponding user. SIMP server waits on UDP port 8002, clients wait on UDP port 8003. SIMP server
* supports following commands: user, pass, send, ask, sendfile, bye.
* user command allowing a user to send his/her username to the server.
* pass command allowing a user to send his/her password to the server. Only the user command executed should
* the pass command be invoked. If the user-pass pair matches a record in the user list, the user is ready to working.
* ask command asking the server if a specific user is online, usage: ask user. If the user is online, the server
* returns yes, otherwise no.
* send command sending a message to a user, usage: send user. At the end of message, a single period is needed.
* sendfile command send a file to a user, usage: sendfile user file_full_path.
* NOTE: both messages and files should not exceed 512 bytes.
* Datagram format:
* user command: SIMP user username1
* pass command: SIMP pass username1 password
* ask command: SIMP ask username1 username2
* send command: SIMP send username1 username2 0-512 bytes message
* sendfile command: SIMP sendfile username1 username2 filename 0-512 bytes file data
* bye command: SIMP bye username1
* Server response:
* SIMP status_code
* status_code: 100, OK, 200, sending success, 300, client error, 400 server error.</p>
* <p>Copyright: Copyright (c) 2005</p>
* <p>Company: </p>
* @author BLiu
* @version 0.1
*/
import java.net.*;
import java.util.*;
public class SIMPServer {
static int S_OK = 100;
static int SEND_OK = 200;
static int CLIENT_ERROR = 300;
static int SERVER_ERROR = 400;
static String[] commands = { "user", "pass", "send", "sendfile", "ask",
"bye" };
Map userlist;
DatagramSocket skt;
public SIMPServer() {
try {
skt = new DatagramSocket(8002);
userlist = new HashMap();
while (true) {
DatagramPacket pkt = new DatagramPacket(new byte[576], 576);
skt.receive(pkt);
handlePacket(pkt);
}
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
void handlePacket(DatagramPacket pkt) {
byte[] data = pkt.getData();
if (!validPacket(pkt)) {
response(pkt, CLIENT_ERROR);
return;
}
// get command.
int i;
for (i = 5; i < data.length && data[i] != ' '; i++)
;
String command = new String(data, 5, i - 5);
// just ignore the user command.
if (command.equals("user")) {
response(pkt, S_OK);
System.out.println("recieved user command from "
+ pkt.getAddress().toString());
} else if (command.equals("pass"))
handlePass(pkt);
else if (command.equals("ask"))
handleAsk(pkt);
else if (command.equals("send"))
handleSend(pkt);
else if (command.equals("bye"))
handleBye(pkt);
else if (command.equals("sendfile"))
handleSendfile(pkt);
}
void handlePass(DatagramPacket pkt) {
String buf = new String(pkt.getData()).trim();
String tokens[] = buf.split(" ");
int i = 0;
while (i < UserManager.usernames.length) {
if (UserManager.usernames[i].equals(tokens[2])
&& UserManager.passwords[i].equals(tokens[3]))
break;
i++;
}
if (i >= UserManager.usernames.length) {
response(pkt, CLIENT_ERROR);
System.out.println("user " + tokens[2] + " login fault");
} else {
userlist.put(tokens[2], pkt.getSocketAddress());
System.out.println("user " + tokens[2] + " login successfule");
response(pkt, S_OK);
}
}
// check whether pkt is a valid packet, e.g., format, user is login, etc.
boolean validPacket(DatagramPacket pkt) {
byte[] d = pkt.getData();
if (d[0] != 'S' || d[1] != 'I' || d[2] != 'M' || d[3] != 'P') {// bad
// head
System.out.println("bad head frome" + pkt.getAddress().toString());
return false;
}
int i;
for (i = 5; i < d.length && d[i] != ' '; i++)
;
String command = new String(d, 5, i - 5);
boolean validCommand = false;
int k;
for (k = 0; k < commands.length; k++)
if (command.equals(commands[k])) {
validCommand = true;
break;
}
if (!validCommand) { // invalid command
System.out.println("bad command from "
+ pkt.getAddress().toString());
return validCommand;
}
i++;
if (k != 0 && k != 1 && k != 5) {// not user pass & bye command,
// checking whether
// the user is login.
System.out.println("k=" + k);
int j = i;
while (j < d.length && d[j] != ' ')
j++;
String u = new String(d, i, j - i);
if (userlist.get(u) == null) {
System.out.println(u + " is not login");
return false;
}
}
return true;
}
void handleSend(DatagramPacket pkt) {
// pass SIMP send username1
int index = 10, end; // "SIMP send ", 10 bytes.
for (end = index; end < pkt.getData().length
&& pkt.getData()[end] != ' '; end++)
;
// initiating username between index & end.
index = end + 1;
for (end = index; end < pkt.getData().length
&& pkt.getData()[end] != ' '; end++)
;
// target username between index and end.
String nm = new String(pkt.getData(), index, end - index);
System.out.println("send to " + nm + " no space");
SocketAddress sa = (SocketAddress) userlist.get(nm);
if (sa == null) {
response(pkt, CLIENT_ERROR);
System.out.println("invalid reciever from "
+ pkt.getAddress().toString());
} else {
try {
DatagramSocket ds = new DatagramSocket();
DatagramPacket p = new DatagramPacket(pkt.getData(), pkt
.getData().length, sa);
ds.send(p);
} catch (Exception e) {
e.printStackTrace(System.out);
}
System.out.println("packet from " + pkt.getAddress().toString()
+ "rely to " + sa.toString());
response(pkt, SEND_OK);
}
}
void handleAsk(DatagramPacket pkt) {
String buf = new String(pkt.getData()).trim();
String tokens[] = buf.split(" ");
String status = " yes";
if (userlist.get(tokens[3]) == null) {// the user is not online
status = " no";
System.out.println("user " + tokens[3] + " is not login");
}
try {
DatagramSocket ds = new DatagramSocket();
String res = "SIMP " + new Integer(S_OK).toString() + status;
DatagramPacket p = new DatagramPacket(res.getBytes(), res.length(),
pkt.getSocketAddress());
ds.send(p);
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
// implement this method by yourself
void handleSendfile(DatagramPacket pkt) {
// pass SIMP send username1
int index = 14, end; // "SIMP send ", 10 bytes.
for (end = index; end < pkt.getData().length
&& pkt.getData()[end] != ' '; end++)
;
// initiating username between index & end.
index = end + 1;
for (end = index; end < pkt.getData().length
&& pkt.getData()[end] != ' '; end++)
;
// target username between index and end.
String nm = new String(pkt.getData(), index, end - index);
System.out.println("send to " + nm + " no space");
SocketAddress sa = (SocketAddress) userlist.get(nm);
if (sa == null) {
response(pkt, CLIENT_ERROR);
System.out.println("invalid reciever from "
+ pkt.getAddress().toString());
} else {
try {
DatagramSocket ds = new DatagramSocket();
DatagramPacket p = new DatagramPacket(pkt.getData(), pkt
.getData().length, sa);
ds.send(p);
} catch (Exception e) {
e.printStackTrace(System.out);
}
System.out.println("packet from " + pkt.getAddress().toString()
+ "rely to " + sa.toString());
response(pkt, SEND_OK);
}
}
void handleBye(DatagramPacket pkt) {
String buf = new String(pkt.getData()).trim();
String tokens[] = buf.split(" ");
if (userlist.get(tokens[2]) != null) {
userlist.remove(tokens[2]);
System.out.println("user " + tokens[2] + " said bye");
// user logout
} else {
response(pkt, 300);
System.out.println("invalid bye command from "
+ pkt.getSocketAddress().toString());
}
}
void response(DatagramPacket pkt, int status) {
try {
DatagramSocket ds = new DatagramSocket();
String res = "SIMP " + new Integer(status).toString();
DatagramPacket p = new DatagramPacket(res.getBytes(), res.length(),
pkt.getSocketAddress());
ds.send(p);
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
public static void main(String[] args) {
SIMPServer SIMPServer1 = new SIMPServer();
}
}
class UserManager {
static String usernames[] = { "zhang", "wang", "li", "zhao" };
static String passwords[] = { "123", "456", "789", "012" };
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -