--> 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();
}
}
}
}
} }

--> 注意:因为要实现客户端连接到服务端,即客户端要先找到服务端,所以服务端要先开启,再开启服务端...

--> 这是一个弱小的局域网群聊功能...

Java-->实现群聊功能(C/S模式--TCP协议)的更多相关文章

  1. day04-1群聊功能

    多用户即时通讯系统04 4.编码实现03 4.5功能实现-群聊功能实现 4.5.1思路分析 群聊的实现思路和私聊的实现非常类似. 不同的是:私聊时,服务端接收到消息后,只需要找出接收方的socket并 ...

  2. java项目-----客户端与客户端通信--实现群聊功能的代码

    这是这个网络聊天室项目的原理图: 很简单,首先ABCD是4个客户端,当A发送信息给服务器,服务器实现以广播的形式把信息全发给每个人---群发群聊 客户端代码: package com.aa; impo ...

  3. netty实现群聊功能

    [概述] 实现一个网络群聊工具.参与聊天的客户端消息是通过服务端进行广播的. 主要由两块组成:聊天服务器端(ChatServer)和聊天客户端(ChatClient). 聊天服务器(ChatServe ...

  4. Asp.net SignalR 应用并实现群聊功能 开源代码

    ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程.实时 Web 功能是指这样一种功能:当所连接的客户端变得可用时服务 ...

  5. ASP.NET SignalR 与LayIM配合,轻松实现网站客服聊天室(四) 添加表情、群聊功能

    休息了两天,还是决定把这个尾巴给收了.本篇是最后一篇,也算是草草收尾吧.今天要加上表情功能和群聊.基本上就差不多了,其他功能,读者可以自行扩展或者优化.至于我写的代码方面,自己也没去重构.好的,我们开 ...

  6. netty无缝切换rabbitmq、activemq、rocketmq实现聊天室单聊、群聊功能

    netty的pipeline处理链上的handler:需要IdleStateHandler心跳检测channel是否有效,以及处理登录认证的UserAuthHandler和消息处理MessageHan ...

  7. Websocket 群聊功能

    websocket 群聊 前提关闭防火墙 写入代码 from flask import Flask,request,render_template from geventwebsocket.handl ...

  8. 基于koa模块和socket.io模块搭建的node服务器实现通过jwt 验证来渲染列表、私聊、群聊功能

    1. 具体代码在需要的下载 https://gitee.com/zyqwasd/socket 效果: 2. package.json文件 1. 下载基本的模块  修改了start 脚本  nodemo ...

  9. Java网络编程Demo,使用TCP 实现简单群聊功能GroupchatSimple,多个客户端输入消息,显示在服务端的控制台

    效果: 服务端 客户端 实现代码: 服务端 import java.io.IOException; import java.net.ServerSocket; import java.net.Sock ...

随机推荐

  1. 第三方开源框架的下拉刷新列表(QQ比较常用的)。

    PullToRefreshListView是第三方开源框架下拉刷新列表,比较流行的QQ 微信等上面都在用. 下载地址(此开源框架于2013年后不再更新) 点此下载 package com.lixu.k ...

  2. iOS Storyboard 的基本用法

    (Storyboard)是一个能够节省你很多设计手机App界面时间的新特性,下面,为了简明的说明Storyboard的效果,我贴上本教程所完成的Storyboard的截图:  现 在,你就可以清楚的看 ...

  3. IPTables系列:如何配置Ubuntu 14.04中的IPTables防火墙

    IPTables基本命令 在向大家介绍复杂防火墙规则之前,还是先上一些简单的料,让大家对IPTables最为基本的命令有一些简单了解. 首先要说明的是IPTables命令必需以root权限运行,这意味 ...

  4. lucene 过滤结果

    package cn.itcast.h_filter; import java.util.ArrayList; import java.util.List; import org.apache.luc ...

  5. RM报表预览,只有固定的1个订单页面

    明明选了多个记录,预览时,只显示最后一个. 原因: 主项数据的数据集选了报表自带的虚拟数据集了.

  6. bzoj 1036 Tree Count

    题目大意:给出一棵树,每个点有一个权值,要求三种操作:1.修改某个点的权值,2.询问x到y路径上各点的权值最大值,3.询问x到y路径上各点的权值之和. #include <cstdio> ...

  7. swing LayoutManager 和多态

    interface LayoutManager{ void show();}class FlowLayout implements LayoutManager{ public void show(){ ...

  8. JAVA之关于This的用法

    JAVA之关于This的用法   业精于勤,荒于嬉:行成于思,毁于随.——韩愈 用类名定义一个变量的时候,定义的应该只是一个引用,外面可以通过这个引用来访问这个类里面的属性和方法,那们类里面是够也应该 ...

  9. python利用or在列表解析中调用多个函数.py

    python利用or在列表解析中调用多个函数.py """ python利用or在列表解析中调用多个函数.py 2016年3月15日 05:08:42 codegay & ...

  10. php的数据访问

    方法一:过去时方法 $定义一个变量 = $mysql_connect("要连接的服务器,默认是 localhost","登录所使用的用户名,默认是 root", ...