实现功能:
1、服务器中转,客户与客户单独通信
2、一端的信息发送不受另一端的影响(收发消息互不影响)
注:大家参考就好了,不要照搬啊!!!
代码展示:
服务器端:
import java.io.*;
import java.net.*;
public class MultiTalkServer{
public static Socket[] socket=new Socket[10];//建立Socket数组,这里简单编写,用静态数组
static int clientnum=0; //静态成员变量,记录当前客户的个数
public static void main(String args[]) throws IOException {
ServerSocket serverSocket=null;
boolean listening=true;
try{
//创建一个ServerSocket在端口4700监听客户请求
serverSocket=new ServerSocket(4700);
}catch(IOException e) {
System.out.println("Could not listen on port:4700.");
//出错,打印出错信息
System.exit(-1); //退出
}
while(listening){ //循环监听
//监听到客户请求,根据得到的Socket对象和客户计数创建服务线程,并启动之
socket[clientnum]=serverSocket.accept();//保存监听到的客户端,这步很重要
new ServerThread(socket[clientnum],clientnum).start();
clientnum++; //增加客户计数
}
serverSocket.close(); //关闭ServerSocket
}
}
线程:
import java.io.*;
import java.net.*;
public class ServerThread extends Thread{
Socket lssocket=null;
Socket socket=null; //保存与本线程相关的Socket对象
int p;//用来记录这是第几个客户端
static int clientnum; //保存本进程的客户计数
public ServerThread(Socket socket,int num) { //构造函数
this.socket=socket; //初始化socket变量
clientnum=num+1; //初始化clientnum变量
p=num;//这里是从0开始编号客户端
}
public void run() { //线程主体
try{
String line;
//由Socket对象得到输入流,并构造相应的DataInputStream对象,BufferedReader的方法会阻塞,所以不要用
DataInputStream is=new DataInputStream(socket.getInputStream());
while(true){
if(is.available()>0)
{
line=is.readUTF();//读取字符串,格式example: 1 aaa
String[] talk=line.split(" ");//以空格为分隔符分割字符串
int number = Integer.parseInt(talk[0]);//这是要收消息的客户端的编号
System.out.println(p+" is talk to "+number);
lssocket=MultiTalkServer.socket[number];//方便修改os
line="Client "+p+": "+talk[1];
talk[1]=line;//把消息连接上发消息的编号,方便阅读
DataOutputStream os=new DataOutputStream(lssocket.getOutputStream());
os.writeUTF(talk[1]);//向客户端输出该字符串
os.flush();//刷新输出流,使Client马上收到该字符串
if (talk[1].equals("bye")) {
break;
}
}
}//继续循环
is.close(); //关闭Socket输入流
socket.close(); //关闭Socket
}catch(Exception e){
System.out.println("Error:"+e);//出错,打印出错信息
}
}
}
客户端:
import java.io.*;
import java.net.*;
public class TalkClient {
public static void main(String args[]) {
try{
//向本机的4700端口发出客户请求
Socket socket=new Socket("127.0.0.1",4700);
System.out.println(socket);//输出本客户端的编号,方便观察,可删除
//由系统标准输入设备构造BufferedReader对象
BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));
//由Socket对象得到输出流,并构造DataOutputStream对象
DataOutputStream os=new DataOutputStream(socket.getOutputStream());
//由Socket对象得到输入流,并构造相应的DataInputStream对象
DataInputStream is=new DataInputStream(socket.getInputStream());
String readline;
System.out.println("样例输入:编号 消息 example:1 hello");
while(true){//若从标准输入读入的字符串为 "bye"则停止循环
if(sin.ready())//DataOutputStream特有的方法,在不读取的情况下,查看缓冲区是否有可读取的内容
{//如果键盘有输入,即先发消息
readline=sin.readLine();
os.writeUTF(readline);;
os.flush();//刷新输出流,使Server马上收到该字符串
if(readline.equals("bye"))
{
break;
}
}
if(is.available()>0)//如果先收消息,也是先available()查看输入流的长度(未读取的情况下)
{
System.out.println(is.readUTF());
}
} //继续循环
os.close(); //关闭Socket输出流
is.close(); //关闭Socket输入流
socket.close(); //关闭Socket
}catch(Exception e) {
System.out.println("Error"+e); //出错,则打印出错信息
}
}
}
注:收发消息互不影响我用的是一个循环不停的判断,还有一种方法是新建线程(读线程和写线程)