Socket群聊代码

阅读更多

写得不是很规范,但也写挺多的注释了。一般是可以看得懂的啦。没什么特别的功能,仅仅是群聊!ps:玩玩而已。直接贴代码。。。比较适合刚学Socket编程的看。界面的代码是用Netbean直接生成的,显得很笨重!

Code:
  1. //====================Server.java=================================
  2. packagecc.nothing2012.blogServlet;
  3. importjava.io.DataInputStream;
  4. importjava.io.DataOutputStream;
  5. importjava.io.IOException;
  6. importjava.net.InetAddress;
  7. importjava.net.ServerSocket;
  8. importjava.net.Socket;
  9. importjava.util.Vector;
  10. publicclassServer{
  11. privateServerSocketserverSocket;
  12. privateSocketsocket;
  13. privatestaticVectorvector=newVector();
  14. privateServerObjectserverObject;
  15. privatestaticVectorvecIPs=newVector();//记录所有的IP对象
  16. publicServer(){
  17. try{
  18. serverSocket=newServerSocket(55555);
  19. System.out.println("服务器已经启动!");//后台提示
  20. while(true){
  21. try{
  22. socket=serverSocket.accept();//一直在等待连接
  23. p(socket);
  24. finalInetAddressaddress=socket.getInetAddress();
  25. p("那个丫的连接的IP:"+address);
  26. p(vector.size());//打印连接前,登陆客户端的个数。
  27. serverObject=newServerObject(socket);//说明一个客户端连接上了,新建对象线程。
  28. vector.addElement(serverObject);//往向量里面添加一个客户端。
  29. p("add"+address.getHostAddress());
  30. vecIPs.addElement("add"+address.getHostAddress());
  31. serverObject.start();//启动一个线程
  32. p("客户端个数:"+vector.size());//打印连接后,登陆客户端的个数。
  33. p("IP个数:"+vecIPs.size());
  34. }catch(IOExceptione){
  35. e.printStackTrace();
  36. }
  37. }
  38. }catch(IOExceptione){
  39. p("服务器启动失败!");
  40. }
  41. }
  42. publicvoidp(Objecto){
  43. System.out.println(o);
  44. }
  45. publicstaticvoidmain(String[]args){
  46. newServer();
  47. }
  48. classServerObjectextendsThread{
  49. privateDataOutputStreamout=null;
  50. privateDataInputStreamin=null;
  51. privateSocketsocket=null;
  52. //每个连接过来的客户端,将初始化这样的一个对象。
  53. publicServerObject(Socketsocket){
  54. this.socket=socket;
  55. try{
  56. in=newDataInputStream(socket.getInputStream());
  57. out=newDataOutputStream(socket.getOutputStream());
  58. }catch(IOExceptione){
  59. e.printStackTrace();
  60. }
  61. }
  62. publicvoidinitIPs(){//无论是增加还是减少都用此方法来更新在线用户
  63. StringallIPs="";
  64. for(inti=0;i//vecIPs至少为1,故不判空
  65. allIPs=allIPs.concat(vecIPs.get(i));//把ip地址都存放在一个字符串里面
  66. }
  67. try{
  68. for(inti=0;i
  69. Server.vector.get(i).out.writeUTF(allIPs);//输出信息给每个客户端。
  70. }
  71. }catch(IOExceptione1){
  72. e1.printStackTrace();
  73. }
  74. }
  75. //启动线程时,执行
  76. publicvoidrun(){
  77. booleanflag=true;//只是一个标志
  78. intm;
  79. //根据当前的在线用户刷新,在线的用户。每个对象只初始化一次!
  80. initIPs();
  81. while(flag){
  82. try{
  83. Stringmessage=in.readUTF();//输入进来的流,简称输入流,拿到客户端的信息。
  84. System.out.println("IP是"+socket.getInetAddress().getHostAddress()+"的"+message);//后台打印出来
  85. if(message.equals("exit")){//如果接收到"exit"字符串说明运行该线程的客户端断开了连接,则需退出该循环,退出线程
  86. flag=false;//退出循环(指的是本通道关闭,该对象的进程结束)
  87. //try{
  88. //Server.vecIPs.remove(this);//从vecIPs中除去本对象的IPs,估计会出错这儿。
  89. //}catch(NullPointerExceptionee){
  90. //System.out.println("果然出错");
  91. //ee.printStackTrace();
  92. //}
  93. StringtempIP="add"+socket.getInetAddress().getHostAddress();//把此IP从ip向量表里咔嚓掉
  94. for(inti=0;i
  95. if(vecIPs.get(i).equals(tempIP)){
  96. vecIPs.remove(i);
  97. break;
  98. }
  99. }
  100. Server.vector.remove(this);//当客户端关闭时,从Vector里除去本对象
  101. initIPs();//重新初始化各个客户端。
  102. }else{
  103. m=Server.vector.size();//返回共有多少个客户端目前。
  104. for(inti=0;i//给每个客户端发送同样的信息。
  105. Server.vector.get(i).out.writeUTF(message);//输出信息给每个客户端。
  106. }
  107. }
  108. }catch(IOExceptione){
  109. e.printStackTrace();
  110. }
  111. }
  112. }
  113. }
  114. }
Code:
  1. //===================MyJFrame2.java===============================
  2. packagecc.nothing2012.blogServlet;
  3. importjava.awt.event.ActionEvent;
  4. importjava.awt.event.ActionListener;
  5. importjava.awt.event.KeyAdapter;
  6. importjava.awt.event.KeyEvent;
  7. importjava.awt.event.WindowAdapter;
  8. importjava.awt.event.WindowEvent;
  9. importjava.io.DataInputStream;
  10. importjava.io.DataOutputStream;
  11. importjava.io.IOException;
  12. importjava.net.Socket;
  13. importjava.net.UnknownHostException;
  14. importjava.util.Timer;
  15. importjava.util.TimerTask;
  16. importjava.util.Vector;
  17. importjava.util.regex.Matcher;
  18. importjava.util.regex.Pattern;
  19. publicclassMyJrame2extendsjavax.swing.JFrameimplementsRunnable{
  20. publicstaticVectorvectorIP=newVector();
  21. publicstaticVectorvectorIPtemp=newVector();
  22. privateSocketsocket;
  23. privateDataInputStreamin;
  24. privateDataOutputStreamout;
  25. privatebooleanflag=true;//标志如果多个客户端则会出错。
  26. privatebooleanserverClose=false;//标识服务器端是否关闭,true为关闭,false为没关闭
  27. privatestaticfinallongserialVersionUID=1L;
  28. publicMyJrame2(){
  29. initComponents();//用来初始化界面
  30. contorClient();//连接服务器等操作
  31. //this.getRootPane().setDefaultButton(jToggleButton1);
  32. newTimer().schedule(newTimerTask(){
  33. publicvoidrun(){
  34. //for(inti=0;i
  35. //System.out.println(vectorIP.get(i));
  36. //}
  37. //System.out.println(vectorIP.size());
  38. jList1.setListData(vectorIP);
  39. }
  40. },2000,3000);
  41. }
  42. publicStringgetMessage(){
  43. if(!(jTextField2.getText()).equals("")){//如果写的东西不为空
  44. if(!(jTextField1.getText()).equals("")){//判断是谁写的信息
  45. return(jTextField1.getText()+":"+jTextField2.getText());
  46. }else{
  47. return("默认是骚包:"+jTextField2.getText());//无名氏默认是ClientX
  48. }
  49. }else{//什么都没写
  50. return"";
  51. }
  52. }
  53. publicvoidsetMessage(Stringmessage){
  54. jTextArea1.append(message+"/n");//添加信息并换行。
  55. }
  56. publicvoidcontorClient(){
  57. try{
  58. socket=newSocket("xxx.xx.xxx.xxx",55555);//此处新建了一个Socket,并连接服务器
  59. //。通信从此位置开始。
  60. jButton1.addActionListener(newActionListener(){//“发送”按钮监听
  61. publicvoidactionPerformed(ActionEvente){//监听按钮的方法。
  62. //必须实现的
  63. //。
  64. try{
  65. if(!serverClose){//第一次执行时,默认是开着的。之后,如果服务器开着,
  66. //即没有关闭,则发送下面内容
  67. Stringmessage=getMessage();//取得某人写的某些内容
  68. if(!message.equals("")){
  69. out=newDataOutputStream(socket
  70. .getOutputStream());
  71. out.writeUTF(message);//把message通过s输出去
  72. jTextField2.setText("");//此处只有发送按钮在监听,
  73. //故发送之后
  74. //,内容理应删掉。
  75. }
  76. }
  77. }catch(IOExceptionioe){
  78. ioe.printStackTrace();
  79. }
  80. }
  81. });
  82. this.addWindowListener(newWindowAdapter(){//监听客户端是否关闭,如果关闭,
  83. //则向服务器发送一个
  84. //“exit”字符串
  85. publicvoidwindowClosing(WindowEvente){
  86. try{
  87. if(serverClose){//serverClose的值一直都是false。
  88. //此处永远不会被执行。
  89. }else{//因为监听到了窗口被关闭了。
  90. out=newDataOutputStream(socket
  91. .getOutputStream());
  92. out.writeUTF("exit");//既然关闭了,就发送个信号给服务器。
  93. //删除该客户端。
  94. }
  95. }catch(IOExceptione1){
  96. e1.printStackTrace();
  97. }
  98. }
  99. });
  100. //只是实现了enter键的触发而已。
  101. jTextField2.addKeyListener(newKeyAdapter(){
  102. publicvoidkeyPressed(KeyEventevent){
  103. if(event.getKeyCode()==KeyEvent.VK_ENTER){
  104. try{
  105. if(!serverClose){//第一次执行时,默认是开着的。之后,如果服务器开着,即没有关闭
  106. //,则发送下面内容
  107. Stringmessage=getMessage();//取得某人写的某些内容
  108. if(!message.equals("")){
  109. out=newDataOutputStream(socket
  110. .getOutputStream());
  111. out.writeUTF(message);//把message通过s输出去
  112. jTextField2.setText("");//此处只有发送按钮在监听,故发送之后
  113. //,内容理应删掉。
  114. }
  115. }
  116. }catch(IOExceptionioe){
  117. ioe.printStackTrace();
  118. }
  119. }
  120. }
  121. });
  122. newThread(this).start();//打开一个线程,即执行本类的run()函数。
  123. }catch(UnknownHostExceptione){
  124. e.printStackTrace();//打印出错信息而已,别无他意。
  125. }catch(IOExceptione){
  126. serverClose=true;
  127. setMessage("服务器不存在或未打开!");
  128. }
  129. }
  130. privatevoidinitComponents(){
  131. jLabel1=newjavax.swing.JLabel();
  132. jTextField1=newjavax.swing.JTextField();
  133. jLabel2=newjavax.swing.JLabel();
  134. jScrollPane1=newjavax.swing.JScrollPane();
  135. jTextArea1=newjavax.swing.JTextArea();
  136. jTextField2=newjavax.swing.JTextField();
  137. jButton1=newjavax.swing.JButton();
  138. jScrollPane2=newjavax.swing.JScrollPane();
  139. jList1=newjavax.swing.JList();
  140. setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
  141. setTitle("八卦聊天器");
  142. setBackground(newjava.awt.Color(204,204,255));
  143. jLabel1.setFont(newjava.awt.Font("宋体",0,18));//NOI18N
  144. jLabel1.setText("请输入您的昵称:");
  145. jTextField1.setFont(newjava.awt.Font("宋体",0,18));//NOI18N
  146. jTextField1.setForeground(newjava.awt.Color(204,204,255));
  147. jLabel2.setFont(newjava.awt.Font("宋体",0,18));//NOI18N
  148. jLabel2.setText("在线用户IP:");
  149. jTextArea1.setColumns(20);
  150. jTextArea1.setRows(5);
  151. jScrollPane1.setViewportView(jTextArea1);
  152. jButton1.setFont(newjava.awt.Font("宋体",0,18));//NOI18N
  153. jButton1.setText("发送");
  154. jButton1.addActionListener(newjava.awt.event.ActionListener(){
  155. publicvoidactionPerformed(java.awt.event.ActionEventevt){
  156. jButton1ActionPerformed(evt);
  157. }
  158. });
  159. jList1.setModel(newjavax.swing.AbstractListModel(){
  160. privatestaticfinallongserialVersionUID=1L;
  161. String[]strings={"Item1","Item2","Item3","Item4","Item5"};
  162. publicintgetSize(){returnstrings.length;}
  163. publicObjectgetElementAt(inti){returnstrings[i];}
  164. });
  165. jScrollPane2.setViewportView(jList1);
  166. javax.swing.GroupLayoutlayout=newjavax.swing.GroupLayout(getContentPane());
  167. getContentPane().setLayout(layout);
  168. layout.setHorizontalGroup(
  169. layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
  170. .addGroup(layout.createSequentialGroup()
  171. .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
  172. .addGroup(layout.createSequentialGroup()
  173. .addGap(56,56,56)
  174. .addComponent(jLabel1)
  175. .addGap(18,18,18)
  176. .addComponent(jTextField1,javax.swing.GroupLayout.PREFERRED_SIZE,199,javax.swing.GroupLayout.PREFERRED_SIZE))
  177. .addGroup(layout.createSequentialGroup()
  178. .addGap(26,26,26)
  179. .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
  180. .addComponent(jTextField2,javax.swing.GroupLayout.PREFERRED_SIZE,440,javax.swing.GroupLayout.PREFERRED_SIZE)
  181. .addComponent(jScrollPane1,javax.swing.GroupLayout.PREFERRED_SIZE,440,javax.swing.GroupLayout.PREFERRED_SIZE))
  182. .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)))
  183. .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
  184. .addGroup(layout.createSequentialGroup()
  185. .addGap(26,26,26)
  186. .addComponent(jLabel2))
  187. .addGroup(layout.createSequentialGroup()
  188. .addGap(18,18,18)
  189. .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
  190. .addComponent(jButton1,javax.swing.GroupLayout.PREFERRED_SIZE,73,javax.swing.GroupLayout.PREFERRED_SIZE)
  191. .addComponent(jScrollPane2,javax.swing.GroupLayout.PREFERRED_SIZE,152,javax.swing.GroupLayout.PREFERRED_SIZE))))
  192. .addContainerGap(24,Short.MAX_VALUE))
  193. );
  194. layout.setVerticalGroup(
  195. layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
  196. .addGroup(layout.createSequentialGroup()
  197. .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
  198. .addGroup(layout.createSequentialGroup()
  199. .addContainerGap()
  200. .addComponent(jLabel2,javax.swing.GroupLayout.PREFERRED_SIZE,35,javax.swing.GroupLayout.PREFERRED_SIZE))
  201. .addGroup(javax.swing.GroupLayout.Alignment.LEADING,layout.createSequentialGroup()
  202. .addGap(44,44,44)
  203. .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
  204. .addComponent(jLabel1,javax.swing.GroupLayout.PREFERRED_SIZE,40,javax.swing.GroupLayout.PREFERRED_SIZE)
  205. .addComponent(jTextField1,javax.swing.GroupLayout.PREFERRED_SIZE,javax.swing.GroupLayout.DEFAULT_SIZE,javax.swing.GroupLayout.PREFERRED_SIZE))))
  206. .addGap(18,18,18)
  207. .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING,false)
  208. .addComponent(jScrollPane2)
  209. .addComponent(jScrollPane1,javax.swing.GroupLayout.DEFAULT_SIZE,402,Short.MAX_VALUE))
  210. .addGap(18,18,18)
  211. .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
  212. .addComponent(jTextField2,javax.swing.GroupLayout.PREFERRED_SIZE,63,javax.swing.GroupLayout.PREFERRED_SIZE)
  213. .addComponent(jButton1,javax.swing.GroupLayout.PREFERRED_SIZE,48,javax.swing.GroupLayout.PREFERRED_SIZE))
  214. .addGap(39,39,39))
  215. );
  216. pack();
  217. }
  218. privatevoidjButton1ActionPerformed(java.awt.event.ActionEventevt){
  219. }
  220. publicvoidrun(){
  221. System.out.println("MyIPis"
  222. +socket.getInetAddress().getHostAddress());
  223. while(flag){
  224. try{
  225. in=newDataInputStream(socket.getInputStream());
  226. if(vectorIPtemp.size()!=0){
  227. vectorIPtemp.removeAllElements();
  228. }
  229. booleanisIPStr=false;
  230. Stringmessage=in.readUTF();//从服务器发过来的信息
  231. System.out.println("从服务器获取的信息:"+message);
  232. //进行匹配看是否有ip地址
  233. Patternp;
  234. Matcherm;
  235. p=Pattern
  236. .compile("add[0-9]{1,3}//.[0-9]{1,3}//.[0-9]{1,3}//.[0-9]{1,3}");
  237. m=p.matcher(message);//将信息进行匹配。
  238. while(m.find()){
  239. isIPStr=true;//说明是IP字符串。
  240. Stringmessage2=m.group();//取得类似add222.17.110.117的地址。
  241. //判断是否只有发送地址而已
  242. //StringisOnlyIP=message.substring(message2.length());
  243. //if(!isOnlyIP.equals("")){
  244. //setMessage(isOnlyIP);//输出到textArea
  245. //}
  246. //判断vectorIP中是否已存在该IP了。
  247. StringIP=message2.substring(3);
  248. vectorIPtemp.addElement(IP);
  249. /**由于一下只能判断增加去掉一样的IP的情况,故舍弃*/
  250. //booleanisExist=false;
  251. //if(vectorIP!=null){
  252. //for(inti=0;i
  253. //if((vectorIP.get(i).equals(IP))){
  254. ////如果不一样,则继续遍历。如果一样,说明存在改变isExist的值。
  255. //isExist=true;
  256. //break;//遍历时,存在就退出。杯具:第一次是自己,存在。而第二个不存在了,且不判断;故出错。
  257. //}
  258. //}
  259. //}
  260. //if(isExist==false){//不存在就添加
  261. //vectorIP.addElement(IP);
  262. //}
  263. vectorIP.removeAllElements();//先清空,再重新加载。
  264. }
  265. //如果执行了while里面的代码,则说明传过来的信息是做IP处理的。
  266. if(isIPStr==false){
  267. setMessage(message);
  268. }else{
  269. vectorIP=(Vector)vectorIPtemp.clone();//重新赋值给vectorIP
  270. }
  271. }catch(IOExceptione){
  272. serverClose=true;//服务器可能在有客户端存在的时候关闭,此时,客户端输入流会出错,刚执行此处
  273. setMessage("服务器关闭了!");
  274. flag=false;//跳出循环
  275. }
  276. }
  277. }
  278. privatevoidjTextField1ActionPerformed(java.awt.event.ActionEventevt){
  279. //
  280. }
  281. privatevoidjTextField2ActionPerformed(java.awt.event.ActionEventevt){
  282. //
  283. }
  284. publicstaticvoidmain(Stringargs[]){
  285. newMyJrame2().setVisible(true);
  286. }
  287. privatejavax.swing.JButtonjButton1;
  288. privatejavax.swing.JLabeljLabel1;
  289. privatejavax.swing.JLabeljLabel2;
  290. privatejavax.swing.JListjList1;
  291. privatejavax.swing.JScrollPanejScrollPane1;
  292. privatejavax.swing.JScrollPanejScrollPane2;
  293. privatejavax.swing.JTextAreajTextArea1;
  294. privatejavax.swing.JTextFieldjTextField1;
  295. privatejavax.swing.JTextFieldjTextField2;
  296. }


==================

有个很明显的漏洞可以修改在线IP。不过也有个很好的解决方法,那就是在客户端先对信息进行匹配处理。

最后张图:

你可能感兴趣的:(Socket,Swing,Java,八卦,.net)