命令行界面的C/S聊天室应用 (Socket多线程实现)
2015-02-08 17:20
561 查看
命令行界面即在Eclipe控制台输入数据。
服务器端包含多个线程,每个Socket对应一条线程,该线程负责读取对应输入流的数据(从客户端发送过来的数据),并将读到的数据向每个Socket输出流发送一遍(将一个客户端发送的数据"广播给其他客户端"),因此需要在服务器端使用List来保存所有的Socket.
下面是服务器端的实现代码,程序为服务器提供了两个类,一个是创建ServerSocket监听的主类,一个是负责处理每个Socket通信的线程类.
packagecom.net.scday1;
importjava.io.IOException;
importjava.net.ServerSocket;
importjava.net.Socket;
importjava.util.ArrayList;
publicclassMyServer{
//定义保存所有Socket的ArrayList
publicstaticArrayList<Socket>scoketList=newArrayList<Socket>();
publicstaticvoidmain(String[]args){
try{
ServerSocketss=newServerSocket(30000);
while(true){
//此代码会阻塞,将一直等待别人的连接
Sockets=ss.accept();
scoketList.add(s);
//每当客户端连接后启动一条ServerThread线程为该客户端服务
newThread(newServerThread(s)).start();
}
}catch(IOExceptione){
e.printStackTrace();
}
}
}
packagecom.net.scday1;
importjava.io.BufferedReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
importjava.io.PrintStream;
importjava.net.Socket;
/**
*负责处理每个线程通信的线程类
*@authoryulei
*
*/
publicclassServerThreadimplementsRunnable{
//定义当前线程所处理的Socket
Sockets=null;
//该线程所处理Socket所对应的输入流
BufferedReaderbr=null;
publicServerThread(Sockets)throwsIOException{
this.s=s;
//初始化该Socket对应的输入流
br=newBufferedReader(newInputStreamReader(s.getInputStream()));
}
publicvoidrun(){
try{
Stringcontent=null;
//采用循环不断从Socket中读取客户端发送过来的数据
while((content=readFromClient())!=null){
//遍历SocketList中的每个Socket
//将读到的内容向每个Socket发送一次
for(Sockets:MyServer.scoketList){
PrintStreamps=newPrintStream(s.getOutputStream());
ps.println(content);
}
}
}catch(Exceptione){
}
}
//定义读取客户端数据的方法
privateStringreadFromClient(){
try{
returnbr.readLine();
//如果捕获到异常,表明该Socket对应的客户端已经关闭
}catch(IOExceptione){
//删除该Socket
MyServer.scoketList.remove(s);
}
returnnull;
}
}
每个客户端应包含两条线程:一条负责读取用户的键盘输入,并将用户的输入数据写入Socket对应的输出流中;一条负责读取Socket对应输入流中的数据(从服务器发送过来的数据),并将这些数据打印输出。其中,负责读取用户键盘输入的线程由MyClinet负责,也就是由程序的主线程负责。客户端程序代码如下:
packagecom.net.scday1;
importjava.io.BufferedReader;
importjava.io.InputStreamReader;
importjava.io.PrintStream;
importjava.net.Socket;
publicclassMyClient{
publicstaticvoidmain(String[]args)throwsException{
Sockets=newSocket("127.0.0.1",30000);
//客户端启动ClientThread线程不断读取来自服务器的数据
newThread(newClientThread(s)).start();
//获取该Socket对应的输出流
PrintStreamps=newPrintStream(s.getOutputStream());
Stringline=null;
//不断读取键盘输入
BufferedReaderbr=newBufferedReader(newInputStreamReader(System.in));
while((line=br.readLine())!=null){
if(""==line||"".equals(line.trim())){
System.out.println("不允许发送空数据!");
}else{
//将用户的键盘输入内容写入Socket对应的输出流
ps.println(line);
}
}
}
}
packagecom.net.scday1;
importjava.io.BufferedReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
importjava.net.Socket;
publicclassClientThreadimplementsRunnable{
//该线程负责处理的Socket
privateSockets;
//该线程所处理的Socket所对应的输入流
BufferedReaderbr=null;
publicClientThread(Sockets)throwsIOException{
this.s=s;
br=newBufferedReader(newInputStreamReader(s.getInputStream()));
}
@Override
publicvoidrun(){
try{
Stringcontent=null;
//不断读取Socket输入流中的内容,并将这些内容打印输出
while((content=br.readLine())!=null){
System.out.println(content);
}
}catch(Exceptione){
}
}
}
服务器端包含多个线程,每个Socket对应一条线程,该线程负责读取对应输入流的数据(从客户端发送过来的数据),并将读到的数据向每个Socket输出流发送一遍(将一个客户端发送的数据"广播给其他客户端"),因此需要在服务器端使用List来保存所有的Socket.
下面是服务器端的实现代码,程序为服务器提供了两个类,一个是创建ServerSocket监听的主类,一个是负责处理每个Socket通信的线程类.
每个客户端应包含两条线程:一条负责读取用户的键盘输入,并将用户的输入数据写入Socket对应的输出流中;一条负责读取Socket对应输入流中的数据(从服务器发送过来的数据),并将这些数据打印输出。其中,负责读取用户键盘输入的线程由MyClinet负责,也就是由程序的主线程负责。客户端程序代码如下:
相关文章推荐
- 命令行界面的C/S聊天室应用 (Socket多线程实现)
- 使用socket.io+redis来实现基本的聊天室应用场景
- Java 多线程Socket编程通讯--实现聊天室代码
- Python socket C/S结构的聊天室应用实现
- Android-Socket多线程应用(聊天室客户端、Handler的简单使用)
- Android-Socket多线程应用(聊天室客户端、Handler的简单使用)
- Python socket C/S结构的聊天室应用实现
- 使用socket.io+redis来实现基本的聊天室应用场景
- 使用 异步多线程TCP Socket 实现进程间通信(VC 6.0 , BCB6.0调试通过)
- 基于Socket的聊天室实现原理
- 用WebBrowser实现HTML界面的应用
- 用WebBrowser实现HTML界面的应用
- 基于Socket的聊天室实现原理
- 用WebBrowser实现HTML界面的应用
- 实现服务器端的多线程SOCKET Server(转)
- 基于socket的聊天室实现原理
- 基于Socket的聊天室实现原理
- 基于Socket的聊天室实现原理
- 实现服务器端的多线程SOCKET Server(转)
- API写的ServerSocket多线程应用例子