`

JAVA范例 十五)网络编程

 
阅读更多

     

  15.1 IP地址

  实例270 获取计算机名与IP地址

import java.net.InetAddress;

public class NetDemo_1 {
	public static void main(String[] args) {
		try {
			InetAddress ind = InetAddress.getLocalHost();
			System.out.println(ind);
		} catch (Exception e) {
			System.out.println("没有找到主机的地址!");
		}
	}
}

 

  实例271 获取网址的IP地址 

import java.net.InetAddress;
import java.net.UnknownHostException;

public class NetDemo_2 {
	public static void main(String[] args) {
		try {
			InetAddress ind = InetAddress.getByName("192.108.33.32");
			System.out.println(ind.getHostName());
			InetAddress ind1 = InetAddress.getByName("www.sina.com");
			System.out.println(ind1);
		} catch (UnknownHostException e) {
			System.out.println(e);
		}
	}
}

 

  实例272 判断两个网址的主机名是否一样 

import java.net.InetAddress;
import java.net.UnknownHostException;

public class NetDemo_3 {
	public static void main(String[] args) {
		try {
			// 创建两个InetAddress的对象
			InetAddress ind = InetAddress.getByName("www.sohu.com");
			InetAddress ind1 = InetAddress.getByName("sohu.com");
			if (ind.equals(ind1)) {// 判断两个网址是否一样
				System.out.println("这两个网址所显示的主机名一样!");
			} else {
				System.out.println("这两个网址所显示的主机名不一样。"); // 输出两个网址的主机名不一样
			}
		} catch (UnknownHostException e) {
			// 没有查找到网址对应的主机
			e.printStackTrace();
		}
	}
}

 

  实例273 测试IP的类型

import java.net.InetAddress;
import java.net.UnknownHostException;

public class NetDemo_4 {
	public static int getVersion(InetAddress ia) {		//定义一个整型的静态方法
		byte[] b = ia.getAddress();					//定义一个字节型的数组,并初始化。
		if (b.length == 4) {						//判断这个数组的长度是否等于4
			return 4;							//返回数值4
		} else if (b.length == 16) {
			return 6;
		} else {
			return -1;
		}
	}
	public static char getClass(InetAddress ia) {		//定义一个字符型的静态方法
		byte[] b = ia.getAddress();					//定义一个字节型的数组,并初始化。
		if (b.length != 4) {						//判断这个	字符数组的长度是否不等于4
			throw new IllegalArgumentException("no ipv6 address");//抛出一个非法参数异常
		}
		int firstByte = b[0];						//定义一个整型的变量
		//使用多个if-else语句判断这个整型的变量与十六进制码比较
		if ((firstByte & 0x80) == 0) {
			return 'A';
		} else if ((firstByte & 0xc0) == 0x80) {
			return 'B';
		} else if ((firstByte & 0xe0) == 0xc0) {
			return 'C';
		} else if ((firstByte & 0xF0) == 0xE0) {
			return 'D';
		} else if ((firstByte & 0xF8) == 0xF0) {
			return 'E';
		} else {
			return 'F';
		}
	}
	public static void main(String[] args) {
		InetAddress ia = null;
		try {
			ia = InetAddress.getByName("www.sina.com");//给定一个网络域名
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		int len;
		char king;
		len = getVersion(ia);							//调用方法求出地址的长度
		System.out.println("地址长度为:" + len);
		king = getClass(ia);							//调用方法求出地址的类型
		System.out.println("地址的类型为:" + king);
	}
}

 

  实例274 查找主机

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.UnknownHostException;

public class NetDemo_5 {
	private static String lookup(String host) {
		InetAddress ia;
		byte[] b = null;					// 初始化一个byte类型的数组
		try {
			ia = InetAddress.getByName(host);
		} catch (UnknownHostException e) {
			return "没有找到主机!";
		}
		if (isHostName(host)) {			//判断是否有主机
			String s = "";				//定义一个字符串
			for (int i = 0; i < b.length; i++) {	//循环遍历出主机的字符串
				int c = b[i] < 0 ? (b[i] + 256) : b[i];
				s += c;
				if (i != b.length - 1) {
					s += ",";
				}
			}
			return s;  						//返回一个字符串
		} else {
			return ia.getHostName();				//返回一个字符串的
		}
	}
	private static boolean isHostName(String host) {	//创建一个静态的方法
		char[] ch = host.toCharArray(); 				//定义一个字符数组,并初始化
		for (int i = 0; i < ch.length; i++) {
			if (!Character.isDigit(ch[i])) {
				if (ch[i] != '.') {
					return true;
				}
			}
		}
		return false;
	}
	public static void main(String[] args) {
		if (args.length > 0) {
			for (int i = 0; i < args.length; i++) { 		// 使用命令行
				System.out.println(lookup(args[i]));
			}
		} else {
			BufferedReader br = new BufferedReader(new InputStreamReader(
					System.in));
			System.out.println();
			while (true) {
				try {
					String s = br.readLine();
					if (s.equals("exit")) {  		//判断如果字符串与“exit”相同,就结束当前的语句块
						break;
					}
					System.out.println(lookup(s));
				} catch (IOException e) {
					System.err.println(e);
				}
			}
		}
	}
}

 

  实例275 主机所支持的协议

  15.2 URL类的使用

  实例276 使用URL访问网页

import java.applet.Applet;
import java.awt.GridLayout;
import java.awt.Label;
import java.net.MalformedURLException;
import java.net.URL;

public class NetDemo_7 extends Applet{
	public void init(){
		URL url = this.getDocumentBase();
		try {
			URL url1 = new URL(url,"a.html"); 	//实例化一个URL对象
			this.setLayout(new GridLayout(2,1));//设置布局
			//添加标签
			this.add(new Label(url.toString()));
			this.add(new Label(url1.toString()));
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} 
	}
}

 

  实例277 URL的组成部分

import java.net.MalformedURLException;
import java.net.URL;
public class NetDemo_8 {
	public static void main(String[] args){
		for(int i=0;i<args.length;i++){
			try {
				URL url = new URL(args[i]);
				System.out.println("URL的地址是:"+url);
				System.out.println("URL的协议是:"+url.getProtocol());
				System.out.println("用户信息是:"+url.getUserInfo());
				String s = url.getHost();
				if(s!=null){
					int it = s.indexOf('@');
					if(it!=-1){
						s= s.substring(it+1);
						System.out.println(s);
					}
				}else{
					System.out.println(args[i]+"域名为空!");
				}
				System.out.println("端口是:"+url.getPort());
				System.out.println("路径是:"+url.getPath());
				System.out.println("文件类型是:"+url.getFile());
				System.out.println("主机名是:"+url.getHost());
			} catch (MalformedURLException e) {
				System.out.println("不是一个URL地址!");
			}
		}
	}
}

 

  实例278 通过指定的URL可以获取网页的源代码

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URL;

public class NetDemo_9 {
	public static void main(String[] args) throws IOException{
		if(args.length>0){
			URL url;
			try {
				url = new URL(args[0]);
				InputStream in = url.openStream();
				in= new BufferedInputStream(in);
				Reader r = new InputStreamReader(in);
				int b;
				while((b = r.read())!=-1){
					System.out.print((char)b);
				}
				Object o = url.getContent();
				System.out.println(o.getClass().getName());
			} catch (MalformedURLException e) {
				e.printStackTrace();
			}catch (Exception e) {
				System.out.print(e);
			}
			
		}
	}
}

 

  实例279 一对多通信模式

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class MySocketServer { 				// 操作Socket服务器端的类
	public static void main(String[] args) { 	// java程序主入口处
		try {
			new StartServer(8080); 		// 传入端口实例化对象
		} catch (Exception e) { 			// 捕获异常
			System.out.println("服务器端进行监听出现异常:" + e.getMessage());
		}
	}
}
class StartServer extends ServerSocket { 	// socket面服务器端
	private int port; 					// 端口
	public StartServer(int port) throws IOException {
		super(port);					// 继承其类的port
		this.port = port;
		System.out.println("服务器启动成功,监听端口号为:" + port);
		System.out.println("正在等待客户连接.........");
		try {
			while (true) { 				// 循环挂起等待客户的请求
				Socket socketCon = accept();
				new RunServer(socketCon, port); 	// 建立服务线程
			}
		} catch (IOException e) {
			System.out.println("没有监听到客户端的信息......");
		} finally {
			close(); 							// 关闭通信资源
		}
	}
}
class RunServer extends Thread { 					// 继承线程类实现服务线程
	private int port; 							// 端口
	private Socket socketCon;
	private BufferedReader in;
	private PrintWriter out;
	public RunServer(Socket s, int port) throws IOException {
		this.port = port;
		this.socketCon = s;
		in = new BufferedReader(new InputStreamReader(socketCon
				.getInputStream(), "gb2312")); 		// 读取客户端的数据流
		// 获取写往客户端的数据输出流,true:自动刷新
		out = new PrintWriter(socketCon.getOutputStream(), true);
		out.println("服务器端连接成功........."); 		// 向客户发送连接信息
		out.println("输入quit断开与服务器的连接");
		start();								// 启动线程
	}
	public String infoUpperCase(String line) { 		// 处理信息
		return line.toUpperCase(); 				// 将字符串大写
	}
	public void run() {
		try {
			boolean done = false;
			while (!done) {
				String line = in.readLine(); // 读取客户端每行的内容
				if (line == null)
					done = true;
				else { 		// 显示客户端发送的内容
					System.out.println("来自客户端的消息:" + line);
					String message = infoUpperCase(line); // 信息处理
							// 向客户端发送信息
					out.println("来自服务器端的消息:" + message);
					if (line.trim().equals("quit")) // 退出判断
						done = true;
				}
			}
			System.out.println("客户端终止发送信息......");
			socketCon.close(); 				// 关闭通信资源
		} catch (Exception e) { 				// 捕获异常
			System.out.println("启动服务器端出现错误:" + e.getMessage());
		}
	}
}
 /**--------文件名:MyOneClient.java-------------*/
class MyOneClient { 					// 操作Socket客户端类
	public static void main(String[] args) { 		// java程序主入口处
		try {
			new Client1("localhost", 8080); 	// IP地址为本机,端口为8080
		} catch (Exception e) { 				// 捕获异常
			System.out.println("测试客户端连接出错:" + e.getMessage());
		}
	}
}
class PointClient { 							// Socket点客户端
	private String host;						// IP地址(域名)
	private int port;							// 端口号
	public PointClient(String host, int port) { 		// 带参数构造方法进行初始化
		this.host = host;
		this.port = port;
		connectServer(); 					// 调用连接方法
	}
	public void connectServer() {				// 连接方法
		try {
			Socket socketConn;				// 声明Socket连接
			// 判断IP地址(域名)如果是本机localhost
			if (host.equals("localhost") || host.equals("127.0.0.1")) {
			// 创建本地连接
				socketConn = new Socket(InetAddress.getLocalHost(), port);
			} else { 						// 创建远程连接
				socketConn = new Socket(InetAddress.getByName(host), port);
			}
			BufferedReader stdin = new BufferedReader(new InputStreamReader(
					System.in)); 	// 获得从键盘输入的流
			PrintWriter out = new PrintWriter(socketConn.getOutputStream(),
					true); 		// 获得服务器写内容的数据流
			BufferedReader in = new BufferedReader(new InputStreamReader(
					socketConn.getInputStream()));		// 获得接收服务器发送内容的缓冲流
			System.out.println("服务器信息:" + in.readLine());	// 从服务器获得信息
			System.out.println("服务器信息:" + in.readLine());
			System.out.print("请输入>"); 					// 用户输入
			boolean done = false;
			while (!done) {
				String line = stdin.readLine(); 				// 获得从键盘输入的每行字符
				out.println(line); 						// 发送到服务端
				if (line.equalsIgnoreCase("quit")) 			// 读到quit则结束循环
					done = true;
				String info = in.readLine(); 				// 从服务器读取字符串
				System.out.println("服务器信息:" + info);		// 显示从服务器发送来的数据
				if (!done) 								// 用户输入
					System.out.print("请输入>");
			}
			socketConn.close(); 						// 关闭资源
		} catch (SecurityException e) { 						// 捕获安全性错误时引发的异常
			System.out.println("连接服务器出现安全问题!");
		} catch (IOException e) { 							// 捕获IO流异常
			System.out.println("连接服务器出现I/O错误!");
		}
	}
}
 /**--------文件名:MyTwoClient.java-------------*/
class MyTwoClient { // 操作Socket客户端类
	public static void main(String[] args) { 	// java程序主入口处
		try {
			new Client1("localhost", 8080); // IP地址为本机,端口为80
		} catch (Exception e) { 			// 捕获异常
			System.out.println("测试客户端连接出错:" + e.getMessage());
		}
	}
}
class Client1 { 							// Socket客户端
	private String host; 					// IP地址(域名)
	private int port; 					// 端口号
	public Client1(String host, int port) { 		// 带参数构造方法进行初始化
		this.host = host;
		this.port = port;
		connectServer(); 				// 调用连接方法
	}
	public void connectServer() { 			// 连接方法
		try {
			Socket socketConn; 		// 声明Socket连接
			// 判断IP地址(域名)如果是本机localhost
			if (host.equals("localhost") || host.equals("127.0.0.1")) {
					// 创建本地连接
				socketConn = new Socket(InetAddress.getLocalHost(), port);
			} else { 	// 创建远程连接
				socketConn = new Socket(InetAddress.getByName(host), port);
			}
			BufferedReader stdin = new BufferedReader(new InputStreamReader(
					System.in)); 	// 获得从键盘输入的流
			PrintWriter out = new PrintWriter(socketConn.getOutputStream(),
					true); 		// 获得服务器写内容的数据流
			BufferedReader in = new BufferedReader(new InputStreamReader(
					socketConn.getInputStream()));		// 获得接收服务器发送内容的缓冲流
			System.out.println("服务器信息:" + in.readLine());	// 从服务器获得信息
			System.out.println("服务器信息:" + in.readLine());
			System.out.print("请输入>"); 					// 用户输入
			boolean done = false;
			while (!done) {
				String line = stdin.readLine(); 				// 获得从键盘输入的每行字符
				out.println(line); 						// 发送到服务端
				if (line.equalsIgnoreCase("quit")) 			// 读到quit则结束循环
					done = true;
				String info = in.readLine(); 				// 从服务器读取字符串
				System.out.println("服务器信息:" + info);		// 显示从服务器发送来的数据
				if (!done) 								// 用户输入
					System.out.print("请输入>");
			}
			socketConn.close(); 						// 关闭资源
		} catch (SecurityException e) { 						// 捕获安全性错误时引发的异常
			System.out.println("连接服务器出现安全问题!");
		} catch (IOException e) { 							// 捕获IO流异常
			System.out.println("连接服务器出现I/O错误!");
		}
	}
}

 

  实例280 自制浏览器

import java.awt.event.WindowEvent;
import java.io.IOException;

import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;



//实现一个浏览器
class LinkFollower implements HyperlinkListener{
	private JEditorPane jep;
	public LinkFollower(JEditorPane jep){
		this.jep= jep;
	}
	public void hyperlinkUpdate(HyperlinkEvent he){
		if(he.getEventType()==HyperlinkEvent.EventType.ACTIVATED){
			try {
				jep.setPage(he.getURL());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
public class NetDemo_15{
	public static void main(String[] args){
		String initPage = "http://www.sina.com";
		if(args.length>0){
			initPage = args[0];
			JEditorPane jep = new JEditorPane();
			jep.setEditable(false);
			jep.addHyperlinkListener(new LinkFollower(jep));
			try {
				jep.setPage(initPage);
			} catch (IOException e) {
				e.printStackTrace();
			}
			JScrollPane jsp = new JScrollPane(jep);
			JFrame jf = new JFrame("简单浏览器");
			jf.setDefaultCloseOperation(WindowEvent.COMPONENT_SHOWN);
			jf.getContentPane().add(jsp);
			jf.setSize(512,324);
			jf.show();
		}
	}
}

 

  实例281 扫描TCP端口

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

public class NetDemo_16 {
	public static void main(String[] args){
		String str = "localhost";
		if(args.length>0){
			str = args[0];
		}
		for(int i=100;i<500;i++){	//使用循环扫描端口
			try {
				Socket s = new Socket();
				System.out.println("There is a server on"+i+"of"+s);
			} catch (Exception e) {
				e.printStackTrace();
				break;
			} 
		}
	}
}

 

  实例282 TCP协议服务器

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class TCPSocketServer {
	public static void main(String[] args) { 		// java程序主入口处
		try {
			Server server = new Server(8080);	// 传入端口号实例化对象
		} catch (Exception e) { 				// 捕获异常
			System.out.println("测试服务器端监听出错:" + e.getMessage());
		}
	}
}
class Server { 								// Socket服务器端
	private int port; 						// 端口
	public Server(int port) { 					// 带参数的构造方法进行初始化
		this.port = port;
		start(); 							// 调用启动服务器端的方法
	}
	public String infoUpperCase(String line) { 	// 处理信息
		return line.toUpperCase(); 			// 将字符串大写
	}
	public void start() { 						// 启动服务器端
		try {
			// 根据端口创建服务器端Socket对象
			ServerSocket serverSocket = new ServerSocket(port);
			// 显示连接信息
			System.out.println("服务器已启动,监听端口号为:" + port);
			System.out.println("正在等待客户端连接.........");
			// 挂起等待客户的请求
			Socket socketAccept = serverSocket.accept();
			BufferedReader in = new BufferedReader(new InputStreamReader(
					socketAccept.getInputStream()));	// 获取读取客户端的数据流
			// 获取写往客户端的数据输出流,true:自动刷新
			PrintWriter out = new PrintWriter(socketAccept.getOutputStream(),
					true);
			out.println("服务器端连接成功........."); 		// 向客户发送连接信息
			out.println("输入quit断开与服务器的连接");
			boolean done = false;
			while (!done) {
				String line = in.readLine(); 			// 读取客户端每行的内容
				if (line == null) { 					// 没有写则不读取
					done = true;
				} else {
					// 显示客户端发送的内容
					System.out.println("来自客户端的信息:" + line);
					// 信息处理
					String message = infoUpperCase(line);
					// 向客户端发送信息
					out.println("来自服务器端的信息:" + message);
					if (line.trim().equals("quit")) 		// 退出判断
						done = true;
				}
			}
			socketAccept.close(); 					// 关闭通信资源
		} catch (Exception e) { 						// 捕获异常
			System.out.println("启动服务器端出现错误:" + e.getMessage());
		}
	}
}

 

  实例283 TCP协议客户机

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;

public class TCPSocketClient {
	public static void main(String[] args) { 	// java程序主入口处
		try {
			new Client("localhost", 8080); 	// IP地址为本机,端口为80
		} catch (Exception e) { 			// 捕获异常
			System.out.println("测试客户端连接出错:" + e.getMessage());
		}
	}
}
class Client { 							// Socket客户端
	private String host; 					// IP地址(域名)
	private int port; 					// 端口号
	public Client(String host, int port) { 		// 带参数构造方法进行初始化
		this.host = host;
		this.port = port;
		connectServer(); 				// 调用连接方法
	}
	public void connectServer() { 			// 连接方法
		try {
			Socket socketConn; 		// 声明Socket连接
			// 判断IP地址(域名)如果是本机localhost
			if (host.equals("localhost") || host.equals("127.0.0.1")) {
				// 创建本地Socket连接
				socketConn = new Socket(InetAddress.getLocalHost(), port);
			} else { // 创建远程Socket连接
				socketConn = new Socket(InetAddress.getByName(host), port);
			}
			BufferedReader stdin = new BufferedReader(new InputStreamReader(
					System.in)); 		// 获得从键盘输入的流
			PrintWriter out = new PrintWriter(socketConn.getOutputStream(),
					true); 			// 获得服务器写内容的数据流
			BufferedReader in = new BufferedReader(new InputStreamReader(
					socketConn.getInputStream()));// 获得接收服务器发送内容的缓冲流
			// 从服务器获得信息
			System.out.println("服务器信息:" + in.readLine());
			System.out.println("服务器信息:" + in.readLine());
			System.out.print("请输入>"); 		// 用户输入
			boolean done = false;
			while (!done) {
				String line = stdin.readLine(); 	// 获得从键盘输入的每行字符
				out.println(line); 			// 发送到服务端
				if (line.equalsIgnoreCase("quit")) 		// 读到quit则结束循环
					done = true;
				String info = in.readLine(); 			// 从服务器读取字符串
				System.out.println("服务器信息:" + info);	// 显示从服务器发送来的数据
				if (!done) 							// 用户输入
					System.out.print("请输入>");
			}
			socketConn.close(); 					// 关闭资源
		} catch (SecurityException e) { 					// 捕获安全性错误时引发的异常
			System.out.println("连接服务器出现安全问题!");
		} catch (IOException e) { 						// 捕获IO流异常
			System.out.println("连接服务器出现I/O错误!");
		}
	}
}

 

  实例284 Socket连接信息

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

public class NetDemo_17 {
	public static void main(String[] args) {
		for (int i = 0; i < args.length; i++) {
			try {
				Socket s = new Socket(args[i], 80);
				System.out.println("Connected to" + s.getInetAddress()
						+ "on port" + s.getPort() + "from port"
						+ s.getLocalPort() + "of" + s.getLocalAddress());
			} catch (UnknownHostException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

 

  实例285 Echo服务的客户端是如何实现的?

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;

public class EchoClient {
	public static void main(String args[]) {
		try {
			Socket connection = new Socket("", 7);// 创建Socket对象,Echo协议对应的端口为7号			System.out.println("已建立连接:");
			DataInputStream in = new DataInputStream(connection
					.getInputStream());// 根据返回的Socket对象的输入流创建数据输入流
			DataOutputStream out = new DataOutputStream(connection
					.getOutputStream());// 根据返回的Socket对象的输出流创建数据输出流
			String line = new String("");
			while (!line.toUpperCase().equals(".QUIT")) {
				System.out.println("输入字符串: ");
				line = EchoClient.readString();// 由键盘输入字符串
				System.out.println("\t字符串发送到服务器 ...");
				out.writeUTF(line);// 以UTF的编码形式将一个字符串写入数据输出流
				System.out.println("\t等待服务器响应 ...");
				line = in.readUTF();// 以UTF的编码形式从数据输入流中读字符串
				System.out.println("Received: " + line);// 将读取的字符串显示出来
			}
			in.close();
			out.close();
			connection.close();
		} catch (UnknownHostException e) {
			System.err.println("Unknown host: " + args[0]);
		} catch (IOException e) {
			System.err.println(e.getMessage());
		}
	}
	public static String readString() {
		String string = new String();
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));// 创建一个可键盘录入的字符串缓冲区
		try {
			string = in.readLine();
		} catch (IOException e) {
		}
		return string;
	}
}

 

  实例286 检测本机的服务端口

import java.io.IOException;
import java.net.ServerSocket;

public class usrLocalPostScanner {
	public static void main(String[] args) {
		// 循环访问端口
		for (int port = 1; port <= 65535; port++) {
			try {
				// 建立新的服务端口
				// 如果在此端口已经有服务存在,则抛出异常
				ServerSocket server = new ServerSocket(port);
			} catch (IOException e) {
				// 打印出异常
				System.out.println("There is a server on port " + port + ".");
			}
		}
	}
}

 

  实例287 下载的页面不丢失链接

import java.net.URLEncoder;

//下载的页面不丢失链接
public class NetDemo_11 {
	public static void main(String[] args){
		System.out.println(URLEncoder.encode("This string has spaces"));
		System.out.println(URLEncoder.encode("This*string*has*asterisks"));
		System.out.println(URLEncoder.encode("This%string%has%persent%signs"));
		System.out.println(URLEncoder.encode("This+string+has+pulses"));
		System.out.println(URLEncoder.encode("This/string/has/slashes"));
		System.out.println(URLEncoder.encode("This:string:has:colors"));
		System.out.println(URLEncoder.encode("This-string-has-tildes"));
		System.out.println(URLEncoder.encode("This(string)has(parentheses)"));
		System.out.println(URLEncoder.encode("This.string.has.periods"));
		System.out.println(URLEncoder.encode("This&string&has&ampersands"));
	}
}

 

  实例288 如何对网页进行重新定向

import java.applet.Applet;
import java.net.MalformedURLException;
import java.net.URL;

//如何对网页进行重新定向
public class NetDemo_12 extends Applet{
	public void init(){
		try {
			getAppletContext().showDocument(new URL("http://delfault.myetang.com"),"_blank");
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
	}
}

 

  实例289 在Internet上搜索对象

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;

//在Intenet上搜索对象
public class NetDemo_13 {
	public static  void main(String[] args) throws IOException{
		String target = "";
		for(int i=0;i<args.length;i++){
			target +=args[i]+"";
		}
		target= target.trim();
		URL url;
		try {
			url = new URL("http://www.baidu.com/");
			InputStream in = new BufferedInputStream(url.openStream());
			InputStreamReader isr = new InputStreamReader(in);
			int b;
			while((b= isr.read())!=-1){
				System.out.print((char)(b));
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		
	}
}

 

  实例290 LAN使用代理服务器

import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.lang.reflect.Constructor;
import java.net.ServerSocket;
import java.net.Socket;

public class LANProxy extends Thread {	// 操作实现代理服务器的类
	protected Socket socket; 			// 传入数据用的Socket
	private static String parent = null; 	// 上级代理服务器
	private static int parentPort = -1;
	public static int RETRIES = 5; 		// 在放弃之前尝试连接远程主机的次数
	public static int PAUSE = 5; 		// 在两次连接尝试之间的暂停时间
	public static int TIMEOUT = 50; 	// 等待Socket输入的等待时间
	public static int BUFSIZ = 1024; 	// 输入的缓冲大小
	public static boolean logging = false; // 是否要求代理服务器在日志中记录所有已传输的数据
	public static OutputStream log = null; // 默认日志例程将向该OutputStream对象输出日志信息
	public void run() { 				// 执行操作的线程
		String line;
		String host;
		int port = 80;
		Socket outbound = null;
		try {
			socket.setSoTimeout(TIMEOUT);		// 设置超时时间
			InputStream is = socket.getInputStream(); // 创建输入流
			OutputStream os = null;
			try {
				line = ""; 						// 获取请求行的内容
				host = "";
				int state = 0;
				boolean space;
				while (true) { 					// 无限循环
					int c = is.read(); 			// 读取输入流的信息
					if (c == -1) 				// 没有读取信息
						break;
					if (logging)
						proxyLog(c, true); 		// 将信息写入日志
					space = Character.isWhitespace((char) c);// 判断是否为空白字符
					switch (state) { 					// 判断状态
					case 0:
						if (space)
							continue; 					// 跳过本次循环
						state = 1; 						// 更改状态
					case 1:
						if (space) {
							state = 2;
							continue; 					// 跳过本次循环
						}
						line = line + (char) c; 			// 添加读取的信息
						break;
					case 2:
						if (space)
							continue; 					// 跳过空白字符
						state = 3; 						// 更改状态
					case 3:
						if (space) { 					// 如果是空白字符
							state = 4; 					// 更改状态
							String host0 = host; 			// 取出网址
							int n;
							n = host.indexOf("//"); 		// 获取网址(不包括协议)
							if (n != -1) 				// 没有找到
								host = host.substring(n + 2);
							n = host.indexOf('/');
							if (n != -1) 				// 没有找到/
								host = host.substring(0, n);
							n = host.indexOf(":"); 		// 分析可能存在的端口号
							if (n != -1) { 				// 没有找到:
								port = Integer.parseInt(host.substring(n + 1));
								host = host.substring(0, n);
							}
							host = outLog(host0, host, port, socket);// 获得网站域名
							if (parent != null) {
								host = parent;
								port = parentPort;
							}
							int retry = RETRIES;
							while (retry-- != 0) {
								try { 							// 创建连接对象
									outbound = new Socket(host, port);
									break;
								} catch (Exception e) {
									System.out.println("无法创建连接:"
											+ e.getMessage());
								}
								Thread.sleep(PAUSE); 			// 设置线程等待
							}
							if (outbound == null)
								break;
							outbound.setSoTimeout(TIMEOUT); 	// 设置超时时间
							os = outbound.getOutputStream(); 		// 获得输出流对象
							os.write(line.getBytes()); 				// 将信息写入流
							os.write(' ');
							os.write(host0.getBytes()); 			// 将信息写入流
							os.write(' ');
							outInfo(is, outbound.getInputStream(), os, socket
									.getOutputStream()); 		// 调用方法将信息写入日志
							break;
						}
						host = host + (char) c;
						break;
					}
				}
			} catch (IOException e) {
			}
		} catch (Exception e) {
		} finally {
			try {
				socket.close(); // 释放资源
			} catch (Exception e1) {
			}
			try {
				outbound.close();
			} catch (Exception e2) {
			}
		}
	}
	void outInfo(InputStream is0, InputStream is1, OutputStream os0,
			OutputStream os1) throws IOException { // 读取流中信息写入日志
		try {
			int ir;
			byte bytes[] = new byte[BUFSIZ]; 		// 创建字节数组,大小:1024
			while (true) {
				try {
					if ((ir = is0.read(bytes)) > 0) { 	// 判断读取输入流的信息
						os0.write(bytes, 0, ir); 	// 读取数据写入输出流对象中
						if (logging)
							proxyLog(bytes, 0, ir, true); // 写入日志
					} else if (ir < 0) // 读取完毕
						break;
				} catch (InterruptedIOException e) { 		// 捕获中断IO流异常
				}
				try {
					if ((ir = is1.read(bytes)) > 0) { 		// 判断读取输入流的信息
						os1.write(bytes, 0, ir); 		// 读取数据写入输出流对象中
						if (logging)
							proxyLog(bytes, 0, ir, false); // 写入日志
					} else if (ir < 0) 					// 读取完毕
						break;
				} catch (InterruptedIOException e) { 		// 捕获中断IO流异常
				}
			}
		} catch (Exception e0) { 						// 捕获异常
		}
	}
	// 用来把一个代理服务器链接到另一个代理服务器(需要指定另一个服务器的名称和端口)。
	public static void setProxy(String name, int port) {
		parent = name;
		parentPort = port;
	}
	public LANProxy(Socket s) { 	// 创建一个代理线程
		socket = s;
		start(); 				// 启动线程
	}
	public void proxyLog(int c, boolean browser) throws IOException {	// 写日志
		log.write(c);
	}
	public void proxyLog(byte[] bytes, int offset, int len, boolean browser)
			throws IOException { 							// 循环写日志
		for (int i = 0; i < len; i++)
			proxyLog((int) bytes[offset + i], browser);
	}
	// 默认情况下,日志信息输出到控制台或文件
	public String outLog(String url, String host, int port, Socket sock) {
		java.text.DateFormat cal = java.text.DateFormat.getDateTimeInstance();
		System.out.println(cal.format(new java.util.Date()) + " - " + url + " "
				+ sock.getInetAddress() + "\n");
		return host;
	}
	public static void startProxy(int port, Class clobj) {
		ServerSocket serverSocket;
		try {
			serverSocket = new ServerSocket(port); 	// 根据端口创建服务器端Socket对象
			while (true) {
				Class[] objClass = new Class[1]; 	// 创建类数组,大小为1
				Object[] obj = new Object[1]; 		// 创建对象数组,大小为1
				objClass[0] = Socket.class;		// 添加Socket类
				try { 							// 创建代理服务器实例
					Constructor cons = clobj.getDeclaredConstructor(objClass);
					obj[0] = serverSocket.accept(); // 挂起等待客户的请求
					cons.newInstance(obj); 		// 创建HttpProxy或其派生类的实例
				} catch (Exception e) {
					Socket socket = (Socket) obj[0];// 对象强制转换
					try {
						socket.close(); 			// 释放资源
					} catch (Exception ec) {
					}
				}
			}
		} catch (IOException e) {
		}
	}
	public static void main(String args[]) { 	// java程序主入口处
		System.out.println("LAN使用代理服务器连接成功......");
		LANProxy.log = System.out; 		// 日志信息输出到控制台
		LANProxy.logging = false;
		LANProxy.startProxy(8080, LANProxy.class);// 调用方法
	}
}

 

  实例291 BBS论坛服务器端

package net;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.*;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.swing.*;
import javax.swing.border.TitledBorder;

/**
 * 聊天室的服务器端程序,GUI界面 
 */
public class BBSServer extends JFrame {
	static JLabel statusBar = new JLabel(); // 状态栏标签

	// 显示客户端的连接信息的列表
	static java.awt.List connectInfoList = new java.awt.List(10);

	// 保存当前处理客户端请求的处理器线程
	static Vector clientProcessors = new Vector(10);

	// 当前的连接数
	static int activeConnects = 0;

	// 构造方法
	public BBSServer() {
		init();
		try {
			// 设置界面为系统默认外观
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
			SwingUtilities.updateComponentTreeUI(this);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void init() {
		this.setTitle("BBS论坛1号聊天室");
		statusBar.setText("");
		// 初始化菜单
		JMenu fileMenu = new JMenu();
		fileMenu.setText("文件");
		JMenuItem exitMenuItem = new JMenuItem();
		exitMenuItem.setText("退出");
		exitMenuItem.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				exitActionPerformed(e);
			}
		});
		fileMenu.add(exitMenuItem);

		JMenuBar menuBar = new JMenuBar();
		menuBar.add(fileMenu);
		this.setJMenuBar(menuBar);
		// 将组件进行布局
		JPanel jPanel1 = new JPanel();
		jPanel1.setLayout(new BorderLayout());
		JScrollPane pane = new JScrollPane(connectInfoList);
		pane.setBorder(new TitledBorder(BorderFactory.createEtchedBorder(
				Color.red, new Color(134, 134, 0)), "客户端IP一览表"));
		jPanel1.add(new JScrollPane(pane), BorderLayout.CENTER);

		this.getContentPane().setLayout(new BorderLayout());
		this.getContentPane().add(statusBar, BorderLayout.SOUTH);
		this.getContentPane().add(jPanel1, BorderLayout.CENTER);
		this.pack();
	}

	/** 退出菜单项事件 */
	public void exitActionPerformed(ActionEvent e) {
		// 向客户端发送断开连接信息
		sendMsgToClients(new StringBuffer(Message.QUIT_IDENTIFER));
		closeAll(); // 关闭所有的连接
		System.exit(0);
	}

	/** 处理窗口关闭事件 */
	protected void processWindowEvent(WindowEvent e) {
		super.processWindowEvent(e);
		if (e.getID() == WindowEvent.WINDOW_CLOSING) {
			exitActionPerformed(null);
		}
	}

	/** 刷新聊天室,不断刷新clientProcessors,制造最新的用户列表 */
	public static void RefreshRoom() {
		StringBuffer people = new StringBuffer(Message.PEOPLE_IDENTIFER);
		for (int i = 0; i < clientProcessors.size(); i++) {
			MessFromClient c = (MessFromClient) clientProcessors.elementAt(i);
			people.append(Message.SEPERATOR).append(c.clientName);
		}
		// 用sendClients方法向客户端发送用户列表的信息
		sendMsgToClients(people);
	}

	/** 向所有客户端群发消息 */
	public static synchronized void sendMsgToClients(StringBuffer msg) {
		for (int i = 0; i < clientProcessors.size(); i++) {
			MessFromClient c = (MessFromClient) clientProcessors.elementAt(i);
			System.out.println("send msg: " + msg);
			c.send(msg);
		}
	}

	/** 关闭所有连接 */
	public static void closeAll() {
		while (clientProcessors.size() > 0) {
			MessFromClient c = (MessFromClient) clientProcessors.firstElement();
			try {
				// 关闭socket连接和处理线程
				c.socket.close();
				c.toStop();
			} catch (IOException e) {
				System.out.println("Error:" + e);
			} finally {
				clientProcessors.removeElement(c);
			}
		}
	}

	/**
	 * 判断客户端是否合法。 不允许同一客户端重复登陆,所谓同一客户端是指IP和名字都相同。
	 */
	public static boolean isCheck(MessFromClient newclient) {
		if (clientProcessors.contains(newclient)) {
			return false;
		} else {
			return true;
		}
	}

	/**
	 * 断开某个连接,并且从连接列表中删除
	 */
	public static void disconnect(MessFromClient client) {
		disconnect(client, true);
	}

	/**
	 * 断开某个连接,根据要求决定是否从连接列表中删除
	 */
	public static synchronized void disconnect(MessFromClient client,
			boolean toRemoveFromList) {
		try {
			// 在服务器端程序的list框中显示断开信息
			connectInfoList.add(client.clientIP + "断开连接");
			BBSServer.activeConnects--; // 将连接数减1
			String constr = "当前在线人数:" + BBSServer.activeConnects + "人";
			statusBar.setText(constr);
			// 向客户发送断开连接信息
			client.send(new StringBuffer(Message.QUIT_IDENTIFER));
			client.socket.close();
		} catch (IOException e) {
			System.out.println("Error:" + e);
		} finally {
			// 从clients数组中删除此客户的相关socket等信息, 并停止线程。
			if (toRemoveFromList) {
				clientProcessors.removeElement(client);
				client.toStop();
			}
		}
	}

	public static void main(String[] args) {
		BBSServer chatServer1 = new BBSServer();
		chatServer1.setVisible(true);
		System.out.println("Server starting ...");
		ServerSocket server = null;
		try {
			// 服务器端开始侦听
			server = new ServerSocket(Message.SERVER_PORT);
		} catch (IOException e) {
			System.out.println("Error:" + e);
			System.exit(1);
		}
		while (true) {
			// 如果当前客户端数小于MAX_CLIENT个时接受连接请求
			if (clientProcessors.size() < Message.MAX_CLIENT) {
				Socket socket = null;
				try {
					// 收到客户端的请求
					socket = server.accept();
					if (socket != null) {
						System.out.println(socket + "连接");
					}
				} catch (IOException e) {
					System.out.println("Error:" + e);
				}
				// 定义并实例化一个ClientProcessor线程类,用于处理客户端的消息
				MessFromClient c = new MessFromClient(socket);
				if (isCheck(c)) {
					clientProcessors.addElement(c); // 添加到列表
					int connum = ++BBSServer.activeConnects; // 如果客户端合法,则继续
					// 在状态栏里显示连接数
					String constr = "当前在线人数:" + connum + "人";
					BBSServer.statusBar.setText(constr);
					// 将客户socket信息写入list框
					BBSServer.connectInfoList.add(c.clientIP + "连接");
					c.start();
					RefreshRoom(); // 通知所有客户端用户列表发生变化
				} else {
					// 如果客户端不合法
					c.ps.println("不允许重复登陆");
					disconnect(c, false);
				}
			} else {
				// 如果客户端超过了MAX_CLIENT个,则等待一段时间再尝试接受请求
				try {
					Thread.sleep(200);
				} catch (InterruptedException e) {
				}
			}
		}
	}
}

/**
 * 处理客户端发送的请求的线程
 */
class MessFromClient extends Thread {

	Socket socket; // 存储一个连接客户端的socket信息

	String clientName; // 存储客户端的连接姓名

	String clientIP; // 存储客户端的ip信息

	BufferedReader br; // 用来实现接受从客户端发来的数据流

	PrintStream ps; // 用来实现向客户端发送信息的打印流

	boolean running = true;

	/** 构造方法 */
	public MessFromClient(Socket s) {
		socket = s;
		try {
			// 初始化输入输出流
			br = new BufferedReader(new InputStreamReader(socket
					.getInputStream()));
			ps = new PrintStream(socket.getOutputStream());
			// 读取收到的信息,第一条信息是客户端的名字、IP信息
			String clientInfo = br.readLine();

			// 读取信息,根据消息分隔符解析消息
			StringTokenizer stinfo = new StringTokenizer(clientInfo,
					Message.SEPERATOR);
			String head = stinfo.nextToken();
			if (head.equals(Message.CONNECT_IDENTIFER)) {
				if (stinfo.hasMoreTokens()) {
					// 关键字后的第二段数据是客户名信息
					clientName = stinfo.nextToken();
				}
				if (stinfo.hasMoreTokens()) {
					// 关键字后的第三段数据是客户ip信息
					clientIP = stinfo.nextToken();
				}
				System.out.println(head); // 在控制台打印头信息
			}
		} catch (IOException e) {
			System.out.println("Error:" + e);
		}
	}

	/** 向客户端发送消息 */
	public void send(StringBuffer msg) {
		ps.println(msg);
		ps.flush();
	}

	// 线程运行方法
	public void run() {
		while (running) {
			String line = null;
			try {
				// 读取客户端发来的数据流
				line = br.readLine();
			} catch (IOException e) {
				System.out.println("Error" + e);
				BBSServer.disconnect(this);
				BBSServer.RefreshRoom();
				return;
			}
			// 客户已离开
			if (line == null) {
				BBSServer.disconnect(this);
				BBSServer.RefreshRoom();
				return;
			}
			StringTokenizer st = new StringTokenizer(line, Message.SEPERATOR);
			String keyword = st.nextToken();
			// 如果关键字是MSG则是客户端发来的聊天信息
			if (keyword.equals(Message.MSG_IDENTIFER)) {
				StringBuffer msg = new StringBuffer(Message.MSG_IDENTIFER)
						.append(Message.SEPERATOR);
				msg.append(clientName);
				msg.append(st.nextToken("\0"));
				// 再将某个客户发来的聊天信息发送到每个连接客户的聊天栏中
				BBSServer.sendMsgToClients(msg);

			} else if (keyword.equals(Message.QUIT_IDENTIFER)) {
				// 如果关键字是QUIT则是客户端发来断开连接的信息
				BBSServer.disconnect(this); // 服务器断开与这个客户的连接
				// 继续监听聊天室并刷新其他客户的聊天人名list
				BBSServer.RefreshRoom();
				running = false;
			}
		}
	}

	public void toStop() {
		running = false;
	}

	// 覆盖Object类的equals方法
	public boolean equals(Object obj) {
		if (obj instanceof MessFromClient) {
			MessFromClient obj1 = (MessFromClient) obj;
			if (obj1.clientIP.equals(this.clientIP)
					&& (obj1.clientName.equals(this.clientName))) {
				return true;
			}
		}
		return false;
	}

	// 覆盖Object类的hashCode方法
	public int hashCode() {
		return (this.clientIP + Message.SEPERATOR + this.clientName).hashCode();
	}
}

 

package net;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.util.StringTokenizer;
import javax.swing.*;
import javax.swing.border.TitledBorder;

/**
 * 聊天室的客户端程序,GUI界面。
 */
public class BBSClient extends JFrame implements ActionListener {

	// 登陆聊天室的名字标签和输入框
	JLabel nameLabel = new JLabel();

	JTextField nameTextField = new JTextField(15);

	// 连接和断开连接的按钮
	JButton connectButton = new JButton();

	JButton disConnectButton = new JButton();

	JTextArea chatContentTextArea = new JTextArea(9, 30); // 聊天室内容的文本域

	JButton sendMsgButton = new JButton(); // 发送消息的按钮

	JTextField msgTextField = new JTextField(20); // 消息输入框

	JLabel msglabel = new JLabel();

	java.awt.List peopleList = new java.awt.List(10); // 聊天室用户列表

	/** 以下定义数据流和网络变量 */
	Socket soc = null;

	PrintStream ps = null;

	// 客户端侦听服务器消息的线程
	ListenClentThread listener = null;

	public BBSClient() {
		init();
	}

	// 初始化图形界面
	public void init() {
		this.setTitle("欢迎来到1号聊天室");

		// 初始化按钮和标签
		nameLabel.setText("姓名:");
		connectButton.setText("登 录");
		connectButton.addActionListener(this);
		disConnectButton.setText("退 出");
		disConnectButton.addActionListener(this);
		// 设置聊天内容不可编辑
		chatContentTextArea.setEditable(false);
		sendMsgButton.setText("发送信息");
		sendMsgButton.addActionListener(this);
		msgTextField.setText("");

		// panel1放置输入姓名和连接两个按钮
		JPanel panel1 = new JPanel();
		panel1.setLayout(new FlowLayout());
		panel1.add(nameLabel);
		panel1.add(nameTextField);
		panel1.add(connectButton);
		panel1.add(disConnectButton);

		// 用于放置聊天信息显示和聊天人员列表
		JPanel panel2 = new JPanel();
		panel2.setLayout(new FlowLayout());
		JScrollPane pane1 = new JScrollPane(chatContentTextArea);
		pane1.setBorder(new TitledBorder(BorderFactory.createEtchedBorder(
				Color.white, new Color(134, 134, 134)), "聊天内容"));
		panel2.add(pane1);
		JScrollPane pane2 = new JScrollPane(peopleList);
		pane2.setBorder(new TitledBorder(BorderFactory.createEtchedBorder(
				Color.white, new Color(134, 134, 134)), "在线用户"));
		panel2.add(pane2);

		// 用于放置发送信息区域
		JPanel panel3 = new JPanel();
		panel3.setLayout(new FlowLayout());
		panel3.add(msglabel);
		panel3.add(msgTextField);
		panel3.add(sendMsgButton);

		// 将组件添加到界面
		this.getContentPane().setLayout(new BorderLayout());
		this.getContentPane().add(panel1, BorderLayout.NORTH);
		this.getContentPane().add(panel2, BorderLayout.CENTER);
		this.getContentPane().add(panel3, BorderLayout.SOUTH);

		this.pack();

		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
			SwingUtilities.updateComponentTreeUI(this);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/** 关闭聊天室客户端事件 */
	protected void processWindowEvent(WindowEvent e) {
		super.processWindowEvent(e);
		if (e.getID() == WindowEvent.WINDOW_CLOSING) {
			// 如果是关闭聊天室客户端,则断开连接
			disconnect();
			dispose();
			System.exit(0);
		}
	}

	/** 处理按钮事件 */
	public void actionPerformed(ActionEvent event) {
		Object source = event.getSource();
		if (source == connectButton) {
			// 如果点击连接按钮
			if (soc == null) {
				try {
					// 使用端口2525实例化一个本地套接字
					soc = new Socket(InetAddress.getLocalHost(),
							Message.SERVER_PORT);
					System.out.println(soc); // 在控制台打印实例化的结果
					ps = new PrintStream(soc.getOutputStream());// 将ps指向soc的输出流
					// 定义一个字符缓冲存储发送信息
					StringBuffer info = new StringBuffer(
							Message.CONNECT_IDENTIFER)
							.append(Message.SEPERATOR);
					// 其中INFO为关键字让服务器识别为连接信息
					// 并将name和ip用":"分开,在服务器端将用一个
					// StringTokenizer类来读取数据
					String userinfo = nameTextField.getText()
							+ Message.SEPERATOR
							+ InetAddress.getLocalHost().getHostAddress();
					ps.println(info.append(userinfo));
					ps.flush();
					// 将客户端线程实例化,并启动
					listener = new ListenClentThread(this, nameTextField
							.getText(), soc);
					listener.start();
				} catch (IOException e) {
					System.out.println("Error:" + e);
					disconnect();
				}
			}

		} else if (source == disConnectButton) {
			// 如果点击断开连接按钮
			disconnect();

		} else if (source == sendMsgButton) {
			// 如果点击发送按钮
			if (soc != null) {
				// 定义并实例化一个字符缓冲存储发送的聊天信息
				StringBuffer msg = new StringBuffer(Message.MSG_IDENTIFER)
						.append(Message.SEPERATOR);
				// 用打印流发送聊天信息
				ps.println(msg.append(msgTextField.getText()));
				ps.flush();
			}
		}
	}

	/** 断开与服务器的连接 */
	public void disconnect() {
		if (soc != null) {
			try {
				// 用打印流发送QUIT信息通知服务器断开此次通信
				ps.println(Message.QUIT_IDENTIFER);
				ps.flush();
				soc.close(); // 关闭套接字
				listener.toStop();
				soc = null;
			} catch (IOException e) {
				System.out.println("Error:" + e);
			}
		}
	}

	public static void main(String[] args) {
		BBSClient client = new BBSClient();
		client.setVisible(true);
	}

	/** 客户端线程类用来监听服务器传来的信息 */
	class ListenClentThread extends Thread {

		String name = null; // 存储客户端连接后的name信息

		BufferedReader br = null; // 客户端接受服务器数据的输入流

		PrintStream ps = null; // 实现从客户端发送数据到服务器的打印流

		Socket socket = null; // 存储客户端的socket信息

		BBSClient parent = null; // 存储当前运行的ChatClient实例

		boolean running = true;

		// 构造方法
		public ListenClentThread(BBSClient p, String n, Socket s) {
			// 接受参数
			parent = p;
			name = n;
			socket = s;
			try {
				// 实例化两个数据流
				br = new BufferedReader(new InputStreamReader(s
						.getInputStream()));
				ps = new PrintStream(s.getOutputStream());
			} catch (IOException e) {
				System.out.println("Error:" + e);
				parent.disconnect();
			}
		}

		// 停止侦听
		public void toStop() {
			this.running = false;
		}

		// 线程运行方法
		public void run() {
			String msg = null;
			while (running) {
				msg = null;
				try {
					// 读取从服务器传来的信息
					msg = br.readLine();
					System.out.println("receive msg: " + msg);
				} catch (IOException e) {
					System.out.println("Error:" + e);
					parent.disconnect();
				}
				// 如果从服务器传来的信息为空则断开此次连接
				if (msg == null) {
					parent.listener = null;
					parent.soc = null;
					parent.peopleList.removeAll();
					running = false;
					return;
				}

				// 用StringTokenizer类来实现读取分段字符
				StringTokenizer st = new StringTokenizer(msg, Message.SEPERATOR);
				// 读取信息头即关键字用来识别是何种信息
				String keyword = st.nextToken();
				if (keyword.equals(Message.PEOPLE_IDENTIFER)) {
					// 如果是PEOPLE则是服务器发来的客户连接信息
					// 主要用来刷新客户端的用户列表
					parent.peopleList.removeAll();
					// 遍历st取得目前所连接的客户
					while (st.hasMoreTokens()) {
						String str = st.nextToken();
						parent.peopleList.add(str);
					}

				} else if (keyword.equals(Message.MSG_IDENTIFER)) {
					// 如果关键字是MSG则是服务器传来的聊天信息,
					// 主要用来刷新客户端聊天信息区将每个客户的聊天内容显示出来
					String usr = st.nextToken();
					parent.chatContentTextArea.append(usr);
					parent.chatContentTextArea.append(st.nextToken("\0"));
					parent.chatContentTextArea.append("\r\n");

				} else if (keyword.equals(Message.QUIT_IDENTIFER)) {
					// 如果关键字是QUIT则是服务器关闭的信息, 切断此次连接
					System.out.println("Quit");
					try {
						running = false;
						parent.listener = null;
						parent.soc.close();
						parent.soc = null;
					} catch (IOException e) {
						System.out.println("Error:" + e);
					} finally {
						parent.soc = null;
						parent.peopleList.removeAll();
					}
					break;
				}
			}
			// 清除用户列表
			parent.peopleList.removeAll();
		}
	}
}

 

 

  实例292 UDP报文的发送与接收

import java.io.File;
import java.io.FileInputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

/**--------文件名:UDPServer.java-------------*/
public class UDPServer {
	public static void main(String args[]) {
		try {
			System.out.println("UDP服务端启动成功,等待接收消息...");
			if (args.length != 1) {
				throw new IllegalArgumentException("参数个数有误");
			}
			int port = Integer.parseInt(args[0]); 	// 从命令行中获取端口号参数
			// 创建一个socket,侦听这个端口。
			DatagramSocket dsocket = new DatagramSocket(port);
			byte[] buffer = new byte[2048]; 		// 保存接收到的UDP报文的字节数组
			// 创建一个DatagramPacket,将收到的报文写入buffer中。
			// 注意,这里指定了报文的长度,如果收到的UDP报文比2048大,
			// 多余的信息被舍弃
			DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
			// 不断循环,接收数据
			while (true) {
				dsocket.receive(packet); // 等待收到一个数据包
				// 将收到的报文的字节数组封装成字符串。
				String msg = new String(buffer, 0, packet.getLength());
				// 从数据包中取得消息来源的地址
				System.out.println("Receive: "
						+ packet.getAddress().getHostAddress() + ": " + msg);
				// 如果收到QUIT指令,则退出循环。
				if (msg.equalsIgnoreCase("QUIT")) {
					System.out.println("退出UDP服务");
					break;
				}
				packet.setLength(buffer.length); // 重设数据包的长度
			}
			// 关闭socket
			dsocket.close();
		} catch (Exception e) {
			System.err.println(e);
			// System.err.println(usage);
		}
	}
}
/**--------文件名:UDPClient.java-------------*/
class UDPClient {
	public static void main(String args[]) {
		try {
			// 检查参数个数
			if (args.length < 3) {
				throw new IllegalArgumentException("参数个数有误");
			}
			// 域名和端口
			String host = args[0];
			int port = Integer.parseInt(args[1]);
			// 下面构造待发送报文的字节数组
			byte[] message;
			if (args[2].equals("-f")) {
				// 如果第三个参数为 -f,则表示将文件的内容以UDP方式发送
				// 获得待发送的文件对象以及文件的长度
				File f = new File(args[3]);
				int len = (int) f.length();
				// 创建一个足够容纳文件内容的字节数组
				message = new byte[len];
				FileInputStream in = new FileInputStream(f);
				// 将文件内容以字节的方式读到字节数组中
				int bytes_read = 0, n;
				do {
					n = in.read(message, bytes_read, len - bytes_read);
					bytes_read += n;
				} while ((bytes_read < len) && (n != -1));
			} else {
				// 如果第三个参数不是 -f,则将后面的参数当作消息发送
				String msg = args[2];
				for (int i = 3; i < args.length; i++) {
					msg += " " + args[i];
				}
				message = msg.getBytes();
			}
			// 根据域名获取IP地址
			InetAddress address = InetAddress.getByName(host);
			// 初始化一个UDP包。
			// DatagramPacket的构造方法中必须使用InetAddress,而不能是IP地址或者域名
			DatagramPacket packet = new DatagramPacket(message, message.length,
					address, port);
			// 创建一个DatagramSocket,以发送UDP包
			DatagramSocket dsocket = new DatagramSocket();
			dsocket.send(packet);
			System.out.println("send: " + new String(message));
			dsocket.close();
			// 注意:如果在构造DatagramPacket时,不提供IP地址和端口号,
			// 则需要调用DatagramSocket的connect方法,否则无法发送UDP包
			packet = new DatagramPacket(message, message.length);
			dsocket = new DatagramSocket();
			dsocket.connect(address, port);
			dsocket.send(packet);
			System.out.println("Send: " + new String(message));
			dsocket.close();
		} catch (Exception e) {
			System.err.println(e);
		}
	}
}

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics