用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); } } }