命令行界面即在Eclipe控制台输入数据。

服务器端包含多个线程,每个Socket对应一条线程,该线程负责读取对应输入流的数据(从客户端发送过来的数据),并将读到的数据向每个Socket输出流发送一遍(将一个客户端发送的数据"广播给其他客户端"),因此需要在服务器端使用List来保存所有的Socket.

下面是服务器端的实现代码,程序为服务器提供了两个类,一个是创建ServerSocket监听的主类,一个是负责处理每个Socket通信的线程类.

package com.net.scday1;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList; public class MyServer {
//定义保存所有Socket的ArrayList
public static ArrayList<Socket> scoketList=new ArrayList<Socket>();
public static void main(String[] args) { try {
ServerSocket ss=new ServerSocket(30000);
while (true) {
//此代码会阻塞,将一直等待别人的连接
Socket s=ss.accept();
scoketList.add(s);
//每当客户端连接后启动一条ServerThread线程为该客户端服务
new Thread(new ServerThread(s)).start();
} } catch (IOException e) {
e.printStackTrace();
} } }
package com.net.scday1;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
/**
* 负责处理每个线程通信的线程类
* @author yulei
*
*/
public class ServerThread implements Runnable{
//定义当前线程所处理的Socket
Socket s=null;
//该线程所处理Socket所对应的输入流
BufferedReader br=null;
public ServerThread(Socket s) throws IOException{
this.s=s;
//初始化该Socket对应的输入流
br=new BufferedReader(new InputStreamReader(s.getInputStream()));
}
public void run() {
try {
String content=null;
//采用循环不断从Socket中读取客户端发送过来的数据
while((content=readFromClient())!=null){
//遍历SocketList中的每个Socket
//将读到的内容向每个Socket发送一次
for(Socket s:MyServer.scoketList){
PrintStream ps=new PrintStream(s.getOutputStream());
ps.println(content);
}
}
} catch (Exception e) {
}
} //定义读取客户端数据的方法
private String readFromClient(){
try {
return br.readLine();
//如果捕获到异常,表明该Socket对应的客户端已经关闭
} catch (IOException e) {
//删除该Socket
MyServer.scoketList.remove(s);
}
return null;
}
}

每个客户端应包含两条线程:一条负责读取用户的键盘输入,并将用户的输入数据写入Socket对应的输出流中;一条负责读取Socket对应输入流中的数据(从服务器发送过来的数据),并将这些数据打印输出。其中,负责读取用户键盘输入的线程由MyClinet负责,也就是由程序的主线程负责。客户端程序代码如下:

package com.net.scday1;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket; public class MyClient { public static void main(String[] args) throws Exception {
Socket s=new Socket("127.0.0.1",30000);
//客户端启动ClientThread线程不断读取来自服务器的数据
new Thread(new ClientThread(s)).start();
//获取该Socket对应的输出流
PrintStream ps=new PrintStream(s.getOutputStream());
String line=null;
//不断读取键盘输入
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
while((line=br.readLine())!=null){
if(""==line||"".equals(line.trim())){
System.out.println("不允许发送空数据!");
}else{
//将用户的键盘输入内容写入Socket对应的输出流
ps.println(line);
}
}
}
}
package com.net.scday1;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket; public class ClientThread implements Runnable{
//该线程负责处理的Socket
private Socket s;
//该线程所处理的Socket所对应的输入流
BufferedReader br=null;
public ClientThread(Socket s) throws IOException{
this.s=s;
br=new BufferedReader(new InputStreamReader(s.getInputStream()));
}
@Override
public void run() {
try {
String content=null;
//不断读取Socket输入流中的内容,并将这些内容打印输出
while((content=br.readLine())!=null){
System.out.println(content);
}
} catch (Exception e) {
}
}
}
 

命令行界面的C/S聊天室应用 (Socket多线程实现)的更多相关文章

  1. 从前有个聊天室(socket&threading)

    服务器端: # -*- coding: utf-8 -*- import socket, threading con = threading.Condition() HOST = raw_input( ...

  2. WinForm版聊天室复习Socket通信

    聊天室:服务器端-------------客户端 最终演示展示图: 一. 服务器端 对服务端为了让主窗体后台不处理具体业务逻辑,因此对服务端进行了封装,专门用来处理某个客户端通信的过程. 而由于通信管 ...

  3. 使用node.js实现多人聊天室(socket.io、B/S)

    通过B/S架构实现多人聊天,客户端连接服务器,发送信息,服务器接收信息之后返回给客户端. 主要是通过socket.io实现浏览器和服务器之间进行实时,双向和基于事件的通信. socket.io官方文档 ...

  4. 【总结】学习Socket编写的聊天室小程序

    1.前言 在学习Socket之前,先来学习点网络相关的知识吧,自己学习过程中的一些总结,Socket是一门很高深的学问,本文只是Socket一些最基础的东西,大神请自觉绕路. 传输协议 TCP:Tra ...

  5. java 用socket制作一个简易多人聊天室

    代码: 服务器端Server import java.io.*; import java.net.*; import java.util.ArrayList; public class Server{ ...

  6. 基于Node的Web聊天室

    1 项目名称 Web聊天室(<这是NodeJs实战>第二章的一个案例,把整个开发过程记录下来)

  7. 网络基础编程_5.4聊天室-IOCP服务器

    聊天室-IOCP服务器 main 创建完成端口内核对象(CreateIoCompletionPort) 获取核心数并创建线程(GetSystemInfo + CreateThread) 创建套接字并绑 ...

  8. Python Socket 编程——聊天室示例程序

    上一篇 我们学习了简单的 Python TCP Socket 编程,通过分别写服务端和客户端的代码了解基本的 Python Socket 编程模型.本文再通过一个例子来加强一下对 Socket 编程的 ...

  9. Socket.IO聊天室~简单实用

    小编心语:大家过完圣诞准备迎元旦吧~小编在这里预祝大家元旦快乐!!这一次要分享的东西小编也不是很懂啊,总之小编把它拿出来是觉地比较稀奇,而且程序也没有那么难,是一个比较简单的程序,大家可以多多试试~ ...

随机推荐

  1. MPAndroidChart图形联动

    MPAndroidChart图形联动 本篇基于博客MPAndroidChart的K线图上添加均线,两个MPAndroidChart是有联动效果的 原理 获取正在滑动的Chart的触摸事件,将事件同步给 ...

  2. Android支付——支付宝支付总结

    摘要:分享牛系列.分享牛转载.第三方支付,java第三方支付.android第三方支付. 原文地址:http://blog.csdn.net/zwl5670/article/details/51219 ...

  3. logstash处理文件进度记录机制

    假如使用如下配置处理日志 input { file { path => "/home/vagrant/logstash/logstash-2.2.2/dbpool-logs/dev/c ...

  4. mysql进阶(二十六)MySQL 索引类型(初学者必看)

    mysql进阶(二十六)MySQL 索引类型(初学者必看)   索引是快速搜索的关键.MySQL 索引的建立对于 MySQL 的高效运行是很重要的.下面介绍几种常见的 MySQL 索引类型.   在数 ...

  5. Dynamics CRM 视图显示列的拷贝—view layout replicator

    在视图设置的时候很多人会遇到这样的问题,要设置多张视图,而这多张视图可能除了筛选条件不同外其他的均相同,手动去设置是件重复的令人非常头痛的事情,如果能够拷贝那就相当完美了. 本篇即介绍视图显示列的拷贝 ...

  6. Android水印相机

    本篇文章实现的水印相机,类似于qq空间中的水印相机功能,因之前看过一个demo上实现了一个简陋的水印相机功能,觉得挺有意思,就在此基础上进行了修改,优化和完善,并增加了部分功能,使之更接近于qq水印相 ...

  7. 对LCS算法及其变种的初步研究

    LCS的全称为Longest Common Subsequence,用于查找两个字符串中的最大公共子序列,这里需要注意区分子序列与子串,所谓子序列,指的是从前到后,可以跳跃元素筛选,而字串则必须连续筛 ...

  8. 剑指Offer——网易笔试之解救小易——曼哈顿距离的典型应用

    剑指Offer--网易笔试之解救小易--曼哈顿距离的典型应用 前言 首先介绍一下曼哈顿,曼哈顿是一个极为繁华的街区,高楼林立,街道纵横,从A地点到达B地点没有直线路径,必须绕道,而且至少要经C地点,走 ...

  9. Hibernate配置文件current_session_context_class的意思

    转自:http://shuaigg-babysky.iteye.com/blog/563423 此设置的作用如下: What does sessionFactory.getCurrentSession ...

  10. python进行md5加密

    代码函数 import hashlib def md5(str): m = hashlib.md5() m.update(str) return m.hexdigest() f = open('idf ...