是一篇博客中,我们对客户端进行了改造。客户端可以实现多线程,那么服务器端也应该进行改造。服务器端应该分别多个客户端,然后分别进行发送信息,比如,群聊或者是私聊。可以利用之前的容器,建立一个容器进行储存。
并且,我们写一个内部类,方便对服务器端的资源进行访问。
可以看看具体代码
//服务器端代码
package Test02;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class Server {
private List<Mychannel> all=new ArrayList<Mychannel>();
public static void main(String[] args) {
new Server().start();
}
public void start() {
try {
ServerSocket serverSocket = new ServerSocket(7777);
while(true) {
Socket client=serverSocket.accept();
Mychannel mychannel=new Mychannel(client);
all.add(mychannel);
new Thread(mychannel).start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//private List<Mychannel> all=new ArrayList<Mychannel>();
public class Mychannel implements Runnable{
@Override
public void run() {
while(isrunning) {
sendOther(MyReceive());
}
}
private boolean isrunning=true;
private DataInputStream dis;
private DataOutputStream dos;
private String name;
public String MyReceive() {
String string="";
try {
string=dis.readUTF();
} catch (IOException e) {
// TODO Auto-generated catch block
isrunning=false;
CloseUtil.Closeall(dis);
}
return string;
}
public void Mysend(String meg) {
try {
dos.writeUTF(meg);
dos.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
isrunning=false;
CloseUtil.Closeall(dos);
}
}
public void sendOther(String meg) {
if(meg.startsWith("@")) {
String name;
String text;
name= meg.substring(0,meg.indexOf(":"));
text=meg.substring(meg.indexOf(":")+1,meg.length());
for(Mychannel temp:all) {
if(temp.name.equals(name)) {
temp.Mysend(this.name+"悄悄对你说"+text);
}
}
}else {
for(Mychannel temp:all) {
if(temp==this) {
continue;
}else {
temp.Mysend(this.name+"对所有人说:"+meg);
}
}
}
/*for(Mychannel temp:all) {
temp.Mysend(meg);
}*/
}
public Mychannel(Socket client) {
super();
try {
dis=new DataInputStream(client.getInputStream());
dos=new DataOutputStream(client.getOutputStream());
name=dis.readUTF();
Mysend("欢迎您进入聊天室");
sendOther(this.name+"进入聊天室");
} catch (IOException e) {
// TODO Auto-generated catch block
isrunning=false;
CloseUtil.Closeall(dis,dos);
all.remove(this);
}
}
public Mychannel() {
super();
}
}
}
客户端代码
package Test02;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static void main(String[] args) {
try {
Socket client=new Socket(InetAddress.getLocalHost(),7777);
System.out.println("请输入姓名:");
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String name=br.readLine();
if (name.equals("")) {
return ;
}
new Thread(new Send(client, name)).start();
new Thread(new Receive(client)).start();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//客户端的多线程
package Test02;
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 boolean isrunning=true;
private BufferedReader console;
private String name;
public Send(Socket client,String name) {
this();//一定要调用this,否则会报空指针异常,这是因为没有调用this构造出consle类
try {
dos=new DataOutputStream(client.getOutputStream());
this.name=name;
send(this.name);
} catch (IOException e) {
// TODO Auto-generated catch block
isrunning=false;
CloseUtil.Closeall(dos);
}
}
public Send() {
super();
console=new BufferedReader(new InputStreamReader(System.in));
}
public void send(String string) {
if(null!=string&&!string.equals("")) {
try {
dos.writeUTF(string);
dos.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
CloseUtil.Closeall(dos);
isrunning=false;
}
}
}
public String getInfo() {
try {
return console.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "";
}
@Override
public void run() {
while(isrunning) {//一定是while,麻痹上头写成if了,上头了
send(getInfo());
}
}
}
//客户端的多线程
package Test02;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
public class Receive implements Runnable{
private DataInputStream dis;
private boolean isrunning=true;
public Receive(Socket client) {
super();
try {
dis=new DataInputStream(client.getInputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
isrunning=false;
CloseUtil.Closeall(dis);
}
}
public Receive() {
super();
}
public String receive() {
String string="";
try {
string=dis.readUTF();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
isrunning=false;
CloseUtil.Closeall(dis);
}
return string;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(isrunning) {
System.out.println(receive());
}
}
}
测试
从测试结果,看到,还有一些小的BUG,明天我们将进行修改,完善。