⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simpserver.java

📁 模拟SIMP协议间通信,需要配置JDK环境,整个程序对协议的生成是个很好的诠释
💻 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 + -