通过Socket和多线程实现广播和客户端到客户端的通信,私聊时有离线消息。
1.服务器端
2.客户端1,输入end结束通信
3.客户端2,输入end结束通信
1.服务器端
package com.gjy.socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
public class MyServers{
static Socket socket = null;
static Map<String,Client> clients = new HashMap<String,Client>();
static Vector<String> privateMesg = new Vector<String>();
public MyServers() throws IOException{
ServerSocket server=new ServerSocket(5678);
System.out.println("服务器已启动......");
while(true){
socket = server.accept();
Client client = new Client(socket);
String user = client.username;
clients.put(user,client);
System.out.println(client.username+"建立连接");
client.start();
sendPrivateMsg(user,null,null,null);
}
}
/**
*
* @param sender
* @param msge
* @param reciver
* @param type
* @throws IOException
*/
public static void sendMsg(String sender,String msge,String reciver,String type) throws IOException{
if(type.equals("siliao")){
paSend(sender,msge,reciver);
}else{
puSend(sender,msge,reciver);
}
}
/**
* 私聊时发送离线消息
* @param sender消息发送者
* @param msge消息
* @param reciver消息接者
* @param type消息形式(公聊或私聊)
* @throws IOException
*/
public static void sendPrivateMsg(String sender,String msge,String reciver,String type) throws IOException{
System.out.println("privatemsg");
Client client = clients.get(sender);
for(int i =0 ;i<privateMesg.size();i++){
String mString = privateMesg.get(i);
String st[] = mString.split(":");
String reciverString = st[0];
String mg = st[1]+": "+st[2];
if(reciverString.equals(sender)){
client.send(mg);
}
}
}
/**
* 私聊时发关消息
* @param sender消息发送者
* @param msge消息
* @param reciver消息接收者
* @throws IOException
*/
public static void paSend(String sender,String msge,String reciver) throws IOException{
Client msg = clients.get(reciver);
if(msg!=null){
msg.send(msge);
}else{
String mm = reciver+":"+msge;
privateMesg.add(mm);
Client client = clients.get(sender);
client.send(reciver+"不在线,你所发的消息将作为离线消息发送给对方");
}
}
/**
* 公聊时发送消息
* @param sender消息发送者
* @param msge消息
* @param reciver消息接收者
* @throws IOException
*/
public static void puSend(String sender,String msge,String reciver) throws IOException{
Set<String> set = clients.keySet();
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {
String key = (String) iterator.next();
Client client = clients.get(key);
client.send(msge);
}
}
/**
* 关闭通信通道
* @param keys指定关闭某个用户的通道
* @throws IOException
*/
public static void close(String keys) throws IOException{
Client client = clients.get(keys);
if(client!=null){
client.client=null;
clients.remove(keys);
socket=null;
}
}
class Client extends Thread{
private Socket client;
private BufferedReader in;
private PrintWriter out;
private String username;
public Client(Socket c){
client=c;
try{
in=new BufferedReader(new InputStreamReader(client.getInputStream()));
out=new PrintWriter(client.getOutputStream());
username = in.readLine();
}catch(IOException e){
e.printStackTrace();
}
}
public void run(){
try {
String string="";
while(true){
string=in.readLine();
String s[] =string.split(":");
if(s.length==2){
String me = s[0];
String type = me.substring(0,6);
String reciver = me.substring(6,me.length());
String mesg =s[1];
String messString = username+"说:"+mesg;
if(mesg.equals("end")){
MyServers.close(username);
System.out.println(username+"断开连接");
break;
}else{
System.out.println("sending........");
MyServers.sendMsg(username,messString,reciver,type);
}
}
}
} catch (IOException e) {
System.out.println(username+"开始关闭连接");
try {
close(username);
} catch (IOException e1) {
e1.printStackTrace();
}
System.out.println(username+"关闭连接");
}
}
public void send(String str) throws IOException{
out.println(str);
out.flush();
}
}
public static void main(String[] args)throws IOException{
new MyServers();
}
}
2.客户端1,输入end结束通信
package com.gjy.socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.*;
public class MyClient01 implements Runnable{
static Socket socket = null;
static PrintWriter pw = null;
BufferedReader bufferedReader;
Client client;
private static String string = "";
public MyClient01(){
try {
socket = new Socket(InetAddress.getLocalHost(),5678);
System.out.println("建立连接,输入end结束连接");
pw = new PrintWriter(socket.getOutputStream());
pw.println("张三");
pw.flush();
client = new Client(socket);
client.start();
} catch (Exception e) {
System.out.println("连接不成功");
}
}
@Override
public void run() {
bufferedReader = new BufferedReader(new InputStreamReader(System.in));
while (true) {
try {
string = bufferedReader.readLine();
//输入end结束通信
if(string.equals("end")){
MyClient01.Close();
break;
}
if(!"".equals(string)){
//广播
pw.println(InetAddress.getLocalHost()+ ":" +string);
//私聊
//pw.println("siliao李四:"+string);
pw.flush();
}
} catch (IOException e) {
}
}
}
class Client extends Thread{
Socket client;
BufferedReader bufferedReader;
PrintWriter printWriter;
public Client (Socket socket) throws IOException{
this.client = socket;
bufferedReader = new BufferedReader(new InputStreamReader(client.getInputStream()));
printWriter = new PrintWriter(client.getOutputStream());
}
public void run(){
String line = "" ;
try {
while(true){
if(string.equals("end")){
break;
}
line = bufferedReader.readLine();
System.out.println(line);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
System.out.println("服务器被关闭");
}
}
}
public static void Close() throws IOException{
pw.println(InetAddress.getLocalHost() + ":" +string);
pw.flush();
socket = null;
}
public static void main(String args[]){
MyClient01 myClient01 = new MyClient01();
myClient01.run();
}
}
3.客户端2,输入end结束通信
package com.gjy.socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.*;
public class MyClient02 implements Runnable{
static Socket socket = null;
static PrintWriter pw = null;
BufferedReader bufferedReader;
Client client;
private static String string = "";
public MyClient02(){
try {
socket = new Socket(InetAddress.getLocalHost(),5678);
System.out.println("成功建立连接,输入end结束连接");
pw = new PrintWriter(socket.getOutputStream());
pw.println("李四");
pw.flush();
client = new Client(socket);
client.start();
} catch (Exception e) {
System.out.println("连接不成功");
}
}
@Override
public void run() {
bufferedReader = new BufferedReader(new InputStreamReader(System.in));
while (true) {
try {
string = bufferedReader.readLine();
//输入end结束通信
if(string.equals("end")){
MyClient02.Close();
break;
}
if(!"".equals(string)){
//广播
pw.println(InetAddress.getLocalHost()+ ":" +string);
//私聊
//pw.println("siliao张三"+ ":" +string);
pw.flush();
}
} catch (IOException e) {
}
}
}
class Client extends Thread{
Socket client;
BufferedReader bufferedReader;
PrintWriter printWriter;
public Client (Socket socket) throws IOException{
this.client = socket;
bufferedReader = new BufferedReader(new InputStreamReader(client.getInputStream()));
printWriter = new PrintWriter(client.getOutputStream());
}
public void run(){
String line = "" ;
try {
while(true){
if(string.equals("end")){
break;
}
line = bufferedReader.readLine();
System.out.println(line);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
System.out.println("服务器被关闭");
}
}
}
public static void Close() throws IOException{
pw.println(InetAddress.getLocalHost()+ ":" +string);
pw.flush();
socket = null;
}
public static void main(String args[]){
MyClient02 myClient02 = new MyClient02();
myClient02.run();
}
}