实现群发功能的sever-client 端的java程序
主要内容:多线程,TCP网络编程,IO流知识
代码如下:
serverduan
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class server {
private ArrayList<Mychannel> all = new ArrayList<Mychannel>(); //建立管道容器,以统一管理
public static void main(String[] args) throws IOException {
new server().start();
}
/**
* 启动服务器函数
* @throws IOException
*/
private void start() throws IOException
{
ServerSocket server = new ServerSocket(9999);
while (true)
{
Socket client = server.accept();
Mychannel mychannel = new Mychannel(client);
all.add(mychannel); //to manage together
new Thread(mychannel).start(); //one channel
}
}
/**
* 建立消息管道类,为实现每个客户端建立独立的一个线程
* @author lzd
*
*/
private class Mychannel implements Runnable
{
private DataInputStream dis;
private DataOutputStream dos;
private boolean isRunning = true;
public Mychannel(Socket client) {
try {
dis = new DataInputStream(client.getInputStream());
dos = new DataOutputStream(client.getOutputStream());
} catch (IOException e) {
isRunning = false;
CloseUtil.closeAll(dis,dos);
//e.printStackTrace();
}
}
/**
* 实现消息获取
* @return
*/
private String receipt()
{
String mString ="";
try {
mString = dis.readUTF();
} catch (IOException e) {
CloseUtil.closeAll(dis);
isRunning = false;
all.remove(this);
//e.printStackTrace();
}
return mString;
}
/**
* 实现发送消息
* @param mString
*/
private void send(String mString) {
try {
dos.writeUTF("server ->"+ mString );
dos.flush();
} catch (IOException e) {
CloseUtil.closeAll(dos);
isRunning = false;
all.remove(this);
//e.printStackTrace();
}
}
/**
* 实现分发功能
*/
private void sentothers()
{
String msString =this.receipt();
for(Mychannel others :all)
{
if(others == this)
continue;
others.send(msString);
}
}
@Override
public void run() {
while(isRunning)
{
sentothers(); // sent to others
}
}
}
}
client端:
import java.io.IOException;
import java.net.Socket;
public class client {
public static void main(String[] args) throws IOException {
Socket client = new Socket("localhost",9999); //建立客户端(指明server的地址,及端口)
new Thread(new send(client)).start(); //建立发送端线程
new Thread(new receipt(client)).start(); //建立接收端线程
}
}
包装发送类:sent
/**
* 发送类,为线程启动服务
*/
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
public class send implements Runnable {
private DataOutputStream dos ;
private BufferedReader bufferedReader;
private String ms =null;
private boolean isRunning = true;
public send() {
bufferedReader = new BufferedReader(new InputStreamReader(System.in));
}
public send (Socket client) {
this();
try {
dos = new DataOutputStream(client.getOutputStream());
} catch (IOException e) {
//e.printStackTrace();
CloseUtil.closeAll(dos,bufferedReader);
isRunning = false;
}
}
private String getMsFromconsole(BufferedReader bufferedReader) {
try {
return bufferedReader.readLine();
} catch (IOException e) {
//e.printStackTrace();
}
return"";
}
private void send() {
ms = getMsFromconsole(bufferedReader);
if(ms!=null&&!ms.equals(""))
{
try {
dos.writeUTF(ms);
dos.flush();
} catch (IOException e) {
CloseUtil.closeAll(dos,bufferedReader);
isRunning = false;
//e.printStackTrace();
}
}
}
@Override
public void run() {
while(isRunning)
{
send();
}
}
}
包装接收类:sent
/**
* 接收类,为接收线程服务
*/
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
public class receipt implements Runnable{
private DataInputStream dis;
private boolean isRunning = true;
public receipt() {
// TODO Auto-generated constructor stub
}
public receipt(Socket client)
{
try {
dis = new DataInputStream(client.getInputStream());
} catch (IOException e) {
CloseUtil.closeAll(dis);
isRunning = false;
//e.printStackTrace();
}
}
public String receipt() {
String mString ="";
try {
mString = dis.readUTF();
} catch (IOException e) {
//e.printStackTrace();
CloseUtil.closeAll(dis);
isRunning = false;
}
return mString;
}
@Override
public void run() {
while(isRunning)
{
System.out.println(receipt());
}
}
}
异常关闭数据通道类CloseUtil:
/**
* 异常关闭数据流通道类
*/
import java.io.Closeable;
import java.io.IOException;
public class CloseUtil {
public static void closeAll(Closeable... io)
{
for(Closeable temp : io)
{
if(temp != null)
{
try {
temp.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}