用socket写个简单的服务器先,再慢慢扩展功能:
public class ChatServer {
public void setUpServer(int port){
try {
ServerSocket server=new ServerSocket(port);
System.out.println("创建成功"+port);
while(true){
Socket client=server.accept();//等待客户机连结。
OutputStream out=client.getOutputStream();//连结对象的输出即输出到客户机界面
InputStream ins=client.getInputStream();//连结对象的输入即从该界面输入,然后输出到服务器界面
String string="你好 , 欢迎来 javaKe.com\r\n";
byte[] data=string.getBytes();
out.write(data);
out.flush();//强制输出
// int in=0;
// while(in!=13){
// in=ins.read();//得到ASK码
// char c=(char)in;//强制转型,得到字符,然后输出
// //System.out.println("读到字符是"+in);
// System.out.println(c);
// }
String string2= readString(ins);
while(!string2.equals("bye") ){
System.out.println("客户机说"+string2);
string="服务器收到"+string2+"\r\n";
data=string.getBytes();
out.write(data);
out.flush();
string2= readString(ins);
}
string="你好,欢迎再来\r\n";
data=string.getBytes();
out.write(data);
out.flush();
client.close();
}
} catch (Exception e) {
}
}
private String readString(InputStream ins) throws IOException{
int c=0;
String string="";
while(c!=13){
c=ins.read();
string+=(char)c;
}
return string.trim();//去掉尾部空格
}
public static void main(String[] args) {
ChatServer cs=new ChatServer();
cs.setUpServer(8888);
}
}
首先是一个写简单的服务器:
ServerSocket server=new ServerSocket(port);//Port是端口号
Server是服务的意思,ServerSocket则是创建一个服务器。
创建好了之后,需要等待客户机的连,客户机用Socket。
Socket client=server.accept();//等待客户机连结。
连结好之后,需要得到client的输入输出流,再根据需要打印出来:
OutputStream out=client.getOutputStream();//连结对象的输出即输出到客户机界面
InputStream ins=client.getInputStream();//连结对象的输入即从该界面输入,然后输出到服务器界面
在一开始,先显示一个打印一个欢迎的字符串:
String string="你好 , 欢迎光临\r\n";//\n为换行 \r 让光标位于行首
byte[] data=string.getBytes();
out.write(data);
out.flush();//强制输出
这时,强制输出即输出到客户机的界面,即用telnet localhost 端口号就可以充当客户机,然后可以看到“你好 , 欢迎光临” 。
注释掉的代码:
先是一个一个字符输入并打印。在客户机界面输入每一个字符,都会从输入流中用read方法得到,再在控制台输出其ASK码,如果需要转成字符,直接强制转型即可。因为要循环一直读取,可用while,直到读取到换行(ASK码为13)。
如果需要将换行之前的字符串一次性输出,就要用到后面的readString方法(后面还可用readline()方法).trim()方法去掉字符串里面的空格,如不加会有输出乱码。循环读取。
最后在主函数中调用该方法,并给端口号即可实现最基本的通信。
但是这种只能一个客户机和服务器聊,不能多个客户机。这时就可用用到之前学过的多线程了:将每一个accept的client都放到一个线程里去执行,并且把前面的输入输出流的出来也放到线程里,因为这些都是属于这个client的方法。然后只需要在前面的accept方法后面调用线程的start方法即可。
public class ChatServer {
public void setchat(int port) throws IOException{
ServerSocket server=new ServerSocket(port);
System.out.println("创建成功");
while(true){
Socket client=server.accept();
ServerThread st=new ServerThread(client);
st.start();
System.out.println("已启动一个线程去处理");
}
}
public static void main(String[] args) throws IOException {
ChatServer cs=new ChatServer();
cs.setchat(9090);
}
}
线程:
public class ServerThread extends Thread{//线程处理
private Socket clinet;
private OutputStream out;
public ServerThread(Socket client){//构造方法传入client对象
this.clinet=client;
}
public void sendMg(String string) throws IOException{//输出到本身这个客户机窗口
byte[] data=string.getBytes();
out.write(data);
out.flush();
}
public void chatServer(Socket client){
try {
out=client.getOutputStream();
InputStream ins=client.getInputStream();
String s="你好,欢迎来到服务器\r\n";
this.sendMg(s);
String string=readString(ins);
while(!string.equals("bye")){
s="我收到你的话了"+string+"\r\n";//\n为换行 换行之后坐标不一定位于行首。\r 让坐标位于行首
sendMg(s);
string=readString(ins);
}
s="下次再来";
sendMg(s);
client.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public String readString(InputStream ins) throws IOException{
String string="";
int i=0;
while(i!=13){
i=ins.read();
string+=(char)i;
}
return string.trim();
}
public void run(){
chatServer(this.clinet);
}
}
这时,可实现多个客户机同时与服务器通信,只是多个客户机之间不能相互通信。
解决的方法:创建一个放ServerThread类型的ArrayList,每次创建一个client对象,就把该对象加入list。然后在后面遍历这个list,调用ServerThread的sendMg方法即可。 可单独创建一个类,里面放数组,以及遍历list的方法。然后每次有个客户机发消息都调用这个类的遍历输出方法,就可以实现多个客户机之间的通信。
public class chatTools {
private static ArrayList<ServerThread > list=new ArrayList<ServerThread>();
private chatTools(){
};
public static void addClient(ServerThread st) throws IOException{
list.add(st);
ctsendMsg(st.getUser(), "上线了!!目前人数"+list.size() );
}
public static ArrayList<ServerThread> getList(){
return list;
}
public static void ctsendMsg(UserInfo sender,String string) throws IOException{
//给各个客户机发送消息
String msg=sender.getName()+" :"+string;
for(int i=0;i<list.size();i++){
ServerThread st=list.get(i);
st.sendMg(msg);
}
}
}