`

Java学习系列(十七)Java面向对象之开发聊天工具

 
阅读更多

TCP通信
Socket --相当于“虚拟链路两端的插座”。Socket负责完成通信。
ServerSocket --它只负责“接收”连接。它用于产生Socket。

服务器端编程
1) 创建ServerSocket 对象,该对象负责“接收”连接。
2) 如果客户端有连接,ServerSocket 对象调用accept()方法返回一个Socket。
3) 通过IO流读取对方的信息,也可向对方发送数据。

 

客户端编程
1) new Socket()来建立与远程服务器的连接。
2) 通过IO流读取对方的信息,也可向对方发送数据。

举列说明1(简单通信):

 

/**
 * @author lhy
 * @description 服务器端
 */
public class ServerTest {
	public static void main(String[] args) {
		PrintStream ps = null;
		try {
			// ServerSocket只负责“接收”连接,20000为端口号(标识该应用程序)
			ServerSocket ss = new ServerSocket(20000);
			System.out.println("服务器端等待连接...");
			// 接收连接,它会阻塞线程
			Socket socket = ss.accept();

			// ----------------------下面统一面向IO编程--------------------------//
			ps = new PrintStream(socket.getOutputStream());
			ps.println("ServerTest你好");
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			ps.close();
		}
	}

}

 

/**
 * @author lhy
 * @description 客户端
 */
public class ClientTest {
	public static void main(String[] args) {
		BufferedReader br = null;
		try {
			Socket socket = new Socket("192.168.0.8", 20000);

			// ----------------------下面统一面向IO编程--------------------------//
			br = new BufferedReader(new InputStreamReader(socket
					.getInputStream()));
			String line = null;
			while ((line = br.readLine()) != null) {
				System.out.println(line);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				br.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

举列说明2(控制台多人聊天):

 

服务器端:

 

public class ServerTest {
	static Set<Socket> clients = Collections
			.synchronizedSet(new HashSet<Socket>());

	public static void main(String[] args) {
		ServerSocket ss = null;
		try {
			ss = new ServerSocket(20000);
			System.out.println("服务器端等待连接...");
			while (true) {
				// 接收连接,它会阻塞线程
				Socket socket = ss.accept();
				clients.add(socket);
				// 启动线程
				new ServerThread(socket).start();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				ss.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

// 单独封装一个线程类
class ServerThread extends Thread {
	private Socket socket;

	public ServerThread(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		BufferedReader br = null;
		try {
			while (true) {
				// ----------------------下面统一面向IO编程--------------------------//
				br = new BufferedReader(new InputStreamReader(socket
						.getInputStream()));
				String line = null;
				while ((line = br.readLine()) != null) {
					for (Socket s : ServerTest.clients) {
						PrintStream ps = new PrintStream(s.getOutputStream());
						ps.println(line);// 输出各个客户端对应的Socket
					}
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				br.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

客户端:

 

 

public class ChatServer {
	// 定义一个线程安全的Set集合
	public static Set<Socket> clients = Collections
			.synchronizedSet(new HashSet<Socket>());

	public static void main(String[] args) throws IOException {
		// ServerSocket只负责“接受”连接,不能通信
		// 该服务器程序就在30002端口监听
		ServerSocket ss = new ServerSocket(20000);
		System.out.println("服务器等待连接...");
		while (true) { // 这样保证每个客户端有一条线程
			// 接受连接。它会阻塞线程
			Socket socket = ss.accept();// 只要连接成功,它会返回socket
			clients.add(socket);// 每次客户端连接进来,就将该客户端添加到clients集合中
			System.out.println("当前用户数量:" + clients.size());
			new ServerThread(socket).start();
		}
	}
}

class ServerThread extends Thread {
	private Socket socket;

	public ServerThread(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		// -----原來读文件,现在改为读网络,只要改节点
		try {
			BufferedReader socketBr = new BufferedReader(new InputStreamReader(
					socket.getInputStream()));
			String line = null;// line代表从网络中读取数据
			while ((line = socketBr.readLine()) != null) {
				for (Iterator<Socket> it = ChatServer.clients.iterator(); it
						.hasNext();) {
					Socket s = it.next();
					try {

						PrintStream ps = new PrintStream(s.getOutputStream());
						ps.println(line);// 输出到各客户端对应的socket
					} catch (SocketException ex) {
						it.remove();// 捕获到该socket的异常,即表明Socket已经断开
                                                System.out.println("当前用户数量:" + ChatServer.clients.size());
						// ex.printStackTrace();
					}
				}
			}
		} catch (SocketException se) {
			ChatServer.clients.remove(socket);
                        System.out.println("当前用户数量:" + ChatServer.clients.size()); 
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

小结:

 

System.in :读取键盘输入。包装方法:BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

socket.getInputStream():读取网络。包装方法:BufferedReadersocketBr = new BufferedReader(new InputStreamReader(socket.getInputStream()));

socket.getOutputStream():写入(输出到)网络。包装方法:PrintStream socketOut = new PrintStream(socket.getOutputStream());

System.out:输出到屏幕。

下面以之前IO讲的一张图来结束:

 

 

 

分享到:
评论

相关推荐

    Java QQ聊天工具源代码

    所涉及到的知识点:Java面向对象、Lambda表达式、Java Swing技术、多线程技术和网络通信等知识,其中还会用到方方面面的Java基础知识。 ​【相关Java视频课程】: 1、...

    Java版QQ聊天工具源代码

    本代码是Java SE技术实现的QQ聊天工具,所涉及到的知识点:Java面向对象、Lambda表达式、Java Swing技术、多线程技术和网络通信等知识,其中还会用到方方面面的Java基础知识。它是《Java从小白到大牛》第30章实战...

    JAVA上百实例源码以及开源项目源代码

     Java二进制IO类与文件复制操作实例,好像是一本书的例子,源代码有的是独立运行的,与同目录下的其它代码文件互不联系,这些代码面向初级、中级Java程序员。 Java访问权限控制源代码 1个目标文件 摘要:Java源码,...

    java源码包---java 源码 大量 实例

     Java二进制IO类与文件复制操作实例,好像是一本书的例子,源代码有的是独立运行的,与同目录下的其它代码文件互不联系,这些代码面向初级、中级Java程序员。 Java访问权限控制源代码 1个目标文件 摘要:Java源码,...

    Java聊天室源代码

    聊天室是一项应用广泛,并且实用性强...此次设计的聊天室系统虽然其功能简单,但是在开发技术和过程中,能够充分学习和使用JAVA的技术,进一步培养学生面向对象程序设计的思想,加深对面向对象程序设计四大特性的理解。

    JAVA上百实例源码以及开源项目

     Java二进制IO类与文件复制操作实例,好像是一本书的例子,源代码有的是独立运行的,与同目录下的其它代码文件互不联系,这些代码面向初级、中级Java程序员。 Java访问权限控制源代码 1个目标文件 摘要:Java源码,...

    基于Java的即时通讯工具的设计与开发的毕业设计,使用Java SE和Java Socket API开发基本功能

    在开发过程中,我们将遵循面向对象编程原则和良好的编程习惯。我们还将使用Git进行版本控制,并使用JUnit进行单元测试。 ## 结论 本毕设将展示一个基于Java的简单即时通讯工具的设计和开发过程。通过实现基本功能...

    基于java实现聊天系统(java+applet)附项目源码

    Java是一种面向对象的编程语言,它具有安全、可靠、简单、高效、跨平台等特点,被广泛应用于各种类型的应用程序开发。Java程序由Java源代码编写,经过编译后生成Java字节码文件,然后在Java虚拟机上运行。 Java程序...

    java源码包4

     Java二进制IO类与文件复制操作实例,好像是一本书的例子,源代码有的是独立运行的,与同目录下的其它代码文件互不联系,这些代码面向初级、中级Java程序员。 Java访问权限控制源代码 1个目标文件 摘要:Java源码...

    java源码包3

     Java二进制IO类与文件复制操作实例,好像是一本书的例子,源代码有的是独立运行的,与同目录下的其它代码文件互不联系,这些代码面向初级、中级Java程序员。 Java访问权限控制源代码 1个目标文件 摘要:Java源码...

    java源码包2

     Java二进制IO类与文件复制操作实例,好像是一本书的例子,源代码有的是独立运行的,与同目录下的其它代码文件互不联系,这些代码面向初级、中级Java程序员。 Java访问权限控制源代码 1个目标文件 摘要:Java源码...

    Java课程设计实训大作业:记事本+简易计算器+聊天系统+日历+中英查询(含源代码+运行截图+实训报告)

    根据Java面向对象程序设计相关理论,及GUI编程、事件处理、数据库编程等技术,设计一个如下图所示的“中英文释义查询”程序。输入英文单词,查询数据库将对应的中文显示在下框中;输入中文,查询数据库将对应的英文...

    基于Java实现聊天室程序附项目源码分享

    Java是一种面向对象的编程语言,它具有安全、可靠、简单、高效、跨平台等特点,被广泛应用于各种类型的应用程序开发。Java程序由Java源代码编写,经过编译后生成Java字节码文件,然后在Java虚拟机上运行。 Java程序...

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    Java编程老鸟潜心写作,奉献高效率的Java学习心得 完全站在没有编程经验读者的角度,手把手教会读者学习Java 配16小时多媒体教学视频,高效、直观 一一击破Java入门可能会遇到的难点和疑惑 抽丝剥茧,层层推进,让...

    java实现一个简单的即时通讯工具的设计与开发(源代码+论文)

    Java是一种程序设计语言,它具有简单的、完全面向对象以及与平台无关的结构,也具有可移植性、高性能和安全性,并提供了多线程的功能,而Java语言最大的成功之处在于它的平台无关性和具有强大的网络编程功能,基于...

    基于java实现聊天系统的设计于实现附项目源码+文档说明

    Java是一种面向对象的编程语言,它具有安全、可靠、简单、高效、跨平台等特点,被广泛应用于各种类型的应用程序开发。Java程序由Java源代码编写,经过编译后生成Java字节码文件,然后在Java虚拟机上运行。 Java程序...

    成百上千个Java 源码DEMO 4(1-4是独立压缩包)

    用累加器,以对话状态存储起来,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用完毕,从内存中清除…… Java Socket 聊天通信演示代码 2个目标文件...

Global site tag (gtag.js) - Google Analytics