这里有新鲜出炉的Java并发编程示例,程序狗速度看过来!
java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台(即JavaEE(j2ee), JavaME(j2me), JavaSE(j2se))的总称。
这篇文章主要介绍了java利用TCP协议实现小型局域网群聊功能(C/S模式) ,感兴趣的小伙伴们可以参考一下
Java 对TCP协议的支持:
--> java.net包中定义了两个类ServerSocket 和Socket ,分别用来实现双向连接的server 端和client 端。
--> Client 类定义客户端
- package com.dragon.java.tcpchat;
- import java.io.IOException;
- import java.net.Socket;
- import java.net.UnknownHostException;
- /**
- * 客户端
- *
- * @author Auser
- *
- */
- public class Client {
- public static void main(String args[]) throws UnknownHostException,
- IOException {
- Socket client = new Socket("192.168.1.188", 10000);
- // 穿件发送信息的线程
- new ClientSend(client).start();
- // 创建接收信息的线程
- new ClientReceive(client).start(); // 因为要实现聊天功能,而不是只发送一次信息,所以输出流和客户端都不能关闭。
- // client.shutdownOutput();
- // client.close();
- }
- }
--> ClientSend 类 定义客户端向服务端发送信息的线程
- package com.dragon.java.tcpchat;
- import java.io.IOException;
- import java.io.PrintStream;
- import java.net.Socket;
- import java.util.Scanner;
- /**
- * 客户端向服务端发送信息的线程
- *
- * @author Auser
- *
- */
- public class ClientSend extends Thread {
- private Scanner scanner;
- private Socket socket;
- public ClientSend(Socket socket) {
- this.socket = socket;
- }
- @Override public void run() {
- scanner = new Scanner(System. in );
- try {
- PrintStream ps = new PrintStream(socket.getOutputStream());
- String line = "";
- // 阻塞式发送信息
- while ((line = scanner.nextLine()) != null) {
- ps.println(line);
- }
- } catch(IOException e) {
- e.printStackTrace();
- }
- }
- }
--> ClientReceive 类 定义客户端接收服务端信息的线程
- package com.dragon.java.tcpchat;
- import java.io.BufferedReader;
- import java.io.InputStreamReader;
- import java.net.Socket;
- /**
- * 客户端接收信息的线程
- *
- * @author Auser
- *
- */
- public class ClientReceive extends Thread {
- private Socket socket;
- public ClientReceive(Socket socket) {
- this.socket = socket;
- }
- @Override public void run() {
- try {
- BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
- // 按行接收信息
- String line = "";
- while ((line = br.readLine()) != null) {
- System.out.println(line);
- }
- } catch(Exception e) {
- e.printStackTrace();
- }
- }
- }
--> Server 类定义服务端
- package com.dragon.java.tcpchat;
- import java.io.IOException;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.util.ArrayList;
- import java.util.List;
- /**
- * 服务器
- *
- * @author Auser
- *
- */
- public class Server {
- public static void main(String[] args) throws IOException,
- InterruptedException {
- List < Socket > list = new ArrayList < >();
- // 创建服务器端的套接字
- ServerSocket server = new ServerSocket(10000);
- while (true) {
- // 接收客户端的阻塞方法
- Socket socket = server.accept();
- // 设计到多个线程可能会对集合进行增删的操作,要进行同步的处理
- synchronized(list) {
- list.add(socket);
- }
- // 启动一个新的线程去处理这个客户端的交流
- new HandleSocket(socket, list).start();
- } // 因为不知道客户端什么时候发送信息,所以服务端要一直开启不能关闭。
- }
- }
--> HandleSocket 类对连接到服务端的客户端进行操作(上下线通知、屏蔽拉黑、将信息发送到每个客户端等...)
- package com.dragon.java.tcpchat;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.PrintStream;
- import java.net.InetAddress;
- import java.net.Socket;
- import java.util.List;
- /**
- * 处理每个(单个)连接到服务器的客户端的线程
- *
- * @author Auser
- *
- */
- public class HandleSocket extends Thread {
- private Socket socket;
- private List < Socket > list;
- /**
- * 构造方法
- *
- * @param socket
- * 当前连接的客户端
- * @param list
- * 存储已连接客户端的集合
- */
- public HandleSocket(Socket socket, List < Socket > list) {
- this.socket = socket;
- this.list = list;
- }
- /**
- * 线程run方法
- */
- @Override public void run() {
- InetAddress address = socket.getInetAddress(); // 获取连接到服务器的这的客户端的地址
- String ip = address.getHostAddress();
- System.out.println(ip + "上线了!");
- if (ip.equals("192.168.1.117")) {
- synchronized(list) {
- sendToAll(ip + "由于违规操作,已被拉入黑名单!");
- list.remove(socket);
- }
- return;
- }
- try {
- BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "gbk"));
- String line = "";
- while ((line = br.readLine()) != null) {
- String msg = ip + ":" + line;
- System.out.println(msg); // 输出到服务器端的控制台
- // 把这个客户端说的话,发给其他所有的客户端
- sendToAll(msg);
- }
- } catch(IOException e) {
- // e.printStackTrace();
- System.out.println(ip + "下线了!");
- synchronized(list) {
- list.remove(socket);
- }
- }
- }
- /**
- * 把信息发送给所有的客户端,去除当前socket
- *
- * @param msg
- * 发送的信息
- */
- private void sendToAll(String msg) {
- synchronized(list) {
- for (Socket s: list) {
- if (s != socket) {
- try {
- PrintStream ps = new PrintStream(s.getOutputStream());
- ps.println();
- } catch(IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
- }
--> 注意:因为要实现客户端连接到服务端,即客户端要先找到服务端,所以服务端要先开启,再开启服务端...
来源: http://www.phperz.com/article/17/1118/360156.html