本节课目标:
1 :循环等待客户机连接
2 : 创建服务器线程,实现多人聊天
3 : 方法封装,方便调用
一:循环等待客户机连接
问题:服务器只能支持一个客户机连接,不能同时多台客户机连接
解决:循环调用Socket client = ss.accept();//ss连接对象
通过while封装,代码如下:
while(true){
Socket client = ss.accept();
...............//获取输入输出流
...............//发送欢迎字符串至客户机
...............//循环读取字节,读取bye结束
...............//关闭连接
}
二、创建服务器线程,实现多人聊天
问题:当通过while循环获取连接,同样还是无法实现多人连接,因为此时服务器是单线程,当一个客户机连接,必须等待当前客户机结束聊天后才能继续连接下一个客户机。
解决 : 通过线程处理,让每个连接对象并行执行,也就是当一个客户机连接时,服务器启动分线程处理,服务器主线程继续等待下一个客户机连接。
<span style="color:#993399;">//分线程</span>
public class ServerThread extends Thread(){
public void run(){
...............//获取输入输出流
...............//发送欢迎字符串至客户机
...............//循环读取字节,读取bye结束
...............//关闭连接
}
}
<span style="color:#993399;">//主线程</span>
while(true){
Socket client = ss.accept();
ServerThread st = new ServerThread(client);
st.start();
}
三、公共方法提取
原因:一些公共的跟当前类无关,如果调用,为了避免对象传值的麻烦,一般单独封装到一个类中,并公共方法都标志Wie静态,方便调用,如发送消息,接收消息方法!
操作: 1.创建一个NetJava类
2.把发送消息方法和接收消息方法封装到NetJava类中,并
标志为静态的!
public static void sendMsg(OutputStream ous,String msg){}
public static String readMsg(InputStream ins){}
具体代码
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
<span style="color:#993399;">//分线程</span>
public class MyServer {
//创建一个队列,用来存储客户机对象
public ArrayList<ServerThread> list= new ArrayList<ServerThread>();
public static void main(String[] args) {
MyServer ms = new MyServer();
ms.initServer(9090);
}
private void initServer(int port) {
//创建服务器
try {
ServerSocket ss = new ServerSocket(port);
System.out.println("创建服务器成功,等待客户机连接....");
while(true){
Socket server = ss.accept();
System.out.println("客户机成功连接,ip地址为 :"+server.getRemoteSocketAddress());
ServerThread sthread = new ServerThread(server);
list.add(sthread);
sthread.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
<span style="color:#993399;">
//分线程</span>
public class ServerThread extends Thread{
private Socket server;
public String name;
public ServerThread(Socket server){
this.server = server;
}
public void run() {
try {
InputStream ins = server.getInputStream();
OutputStream ous = server.getOutputStream();
String msg = "欢迎来到我的聊天室";
byte[] bytes = msg.getBytes();
ous.write(bytes);
ous.flush();
msg = "请输入姓名:";
ous.write(msg.getBytes());
ous.flush();
//接收客户端输入的姓名
name = readMessage(ins);
System.out.println("用户名为: "+name);
//读取消息
String str = "";
while(!"bye".equals(str)){
str = readMessage(ins);
System.out.println(name+"说 :"+str);
}
ous.close();
ins.close();
server.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//定义一个读取消息的方法
<span style="color:#993399;">//公共方法</span>
public String readMessage(InputStream ins){
StringBuffer sb = new StringBuffer();
try {
int readByte = ins.read();
while(readByte!= 13){
sb.append((char)readByte);
readByte = ins.read();
}
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString().trim();
}
}