三种onClick事件与Java中Socket通信简介

本文详细介绍了Android中三种实现Button点击事件的方法,并对比了它们的特点与适用场景。此外,还深入探讨了Java中Socket通信的基本原理及其实现过程,包括TCP与UDP的区别、单线程与多线程服务器的构建。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

android中三种onClick事件的实现,与对比


  

    在达内培训,刚接触android不久,对于button的onclick事件有点纠结。因为上了两三天就换了个老师,两个老师讲onclick事件用了两种不同的实现方法,我才发现可以有好几种方式实现。

   

方式一:在activity的onCreate()方法中,嵌入如下代码:

 

Button button =(Button)findViewById(R.id.button1);

button.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
TextView textview = (TextView)findViewById(R.id.textView1);
textview.setText("Button");
}
});

这种方式用findviewbyid通过id实例化出来这个button,然后通过设置button的listener监听对象,并同时实现接口OnClickListenter的OnClick()方法。这种方式的代码量不多,但是在java中,面向对象的思想,关于耦合,模块化它达不到。代码堆叠在一起,比较臃肿。

方式二:让acticity持有TextView,并且新建类Button_Listener实现接口OnClickListener,activity中的代码为:

public class TestOnClickActivity extendsActivity {
private TextView textview;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button = (Button)findViewById(R.id.button1);
this.textview = (TextView)findViewById(R.id.textView1);
button.setOnClickListener(new Button_Listener(this));
}

public TextView getTextview() {
return this.textview;
}
}
类Button_Listener的代码为:
class Button_Listener implements OnClickListener {
private TestOnClickActivity activity;

public Button_Listener(TestOnClickActivity activity) {
this.activity = activity;
}

@Override
public void onClick(View v) {
TextView textview = activity.getTextview();
textview.setText("你点击了Button");

}
}

方式二:

在方式二中,为了改正方式一的接口实现的不规范,特别重新建立了一个类:Button_Listener。

这种方式代码结构清晰,在为Button加入监听方法是,只需要newButton_Listener(this)即可。但同时,我们也能够发现,因为不属于类TestOnClickActivity,所以类Button_Listener必须通过持有TestOnClickActivity,将其作为成员。并且,我们需要在TestOnClickActivity中显示的加入TextView,并书写getTextview()方法,才能够实现我们的程序意图。

虽然代码的模块化,解耦化得到了一定程度上的实现,但换来的结果是代码更多,书写更加繁琐。

方式三:在组件文件main.xml中,对Button加入:

android:onClick="onClick_Event"

在activity中加入以下代码:

public void onClick_Event(View view){
TextView textview = (TextView)findViewById(R.id.textView1);
textview.setText("Button");
}

在方式三种,我们只需要在TestOnClickActivity中增加一个成员函数onClick_Event(),并在组件文件中加入对其的使用描述即可。

代码结构简单,清晰,代码量也大大减少,并且通过xml文件的可配置性,增长了工程的可维护性,模块化进一步增强!





&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

简介

Java中Socket通信简介

单线程一对一服务器1——>1客户端

单线程一对一服务器1<——>1客户端

多线程一对多服务器1<——>N客户端【非聊天室的服务器通过用户输入发送数据】

多线程一对多服务器1<——>N客户端【聊天室】

多线程最终服务器和客户端集成一体【swing程序】



    简介:
 
    无论是在Java语言还是C++语言中,初学一个知识点,通常一般都是在dos黑屏中运行。比如开始学习HelloWorld,我们都是在dos黑屏中掌握。
  虽然程序员不在乎设计语言,只要掌握其核心思想原理。但是学习两种语言后,发现对客户端程序很吃力,对窗体形式基础很薄弱。
  也许很多东西只有在控制台中运行即可。但是有些东西在dos黑屏中,确实很难理解或很难给人视觉理解。
  比如socket编程在这方面就是有很大的感触。在C++中dos中运行socket编程,始终无法理解服务器与客户端集成一体。但是结局是,人家在VC窗体中使用CScoket的确集成在一块了。(后来自己窗体中只是做了连接,初步理解服务器与客户端集成一体)。使用底层的winsock32,使用起来不不方便。需要初始化,加载,监听。连接等。(只是初步学者的感觉)但是无论是VC封装的CSocket,还是Java中封装的Socket,使用起来很方便。
 
  Java中Socket通信简介:

 

  那这篇博客就给大家介绍,Java中Socket通信。记录自己是如何一步步理解Socket。希望此博客能够解答像我这样初学者疑惑。
 
  TCP协议与UDP协议区别:
  TCP:安全可靠,不适合传输大数据量的数据。
  UDP:不安全可靠,适合传输大数据量的数据。
 
  对于安全与否,是说的TCP是基于三次握手协议。首先连接,判断对方是否在线或开启服务。然后发送数据,再次是回复收到的标识。
  而UDP而不需要监听,连接。无论对方是否在线或开启服务,直接发送数据。若对方收到数据,也不回复,这样,若丢包,大家都不知道。都以为对方收到了,或者反正发送了,后果怎么样,不管。至少我发送了。
   当然这是主要的区别。若想对两者协议具体区分,比如其中的报文长度什么的,这方面只是建议看看TCP/Ip详解这种类似的书籍。
 
   那Java中TCP协议中的socket通信如下图。我们在理解通信时,会区分服务器和客户端。但是最后,其实,没有说所谓的严格的服务器与客户端。但是为了好理解,我们先划分。
   TCP协议中的Socket通信。
    
     其中:服务器端是用ServerSocket来表示。客户端使用Socket。服务器初始化完毕后,等待客户端连接,若有客户端连接,则两者可以进行通信。两者通信是使用流的形式来表示。
 
     而UDP协议中的Socket通信。
     
     其中,根据UDP特性,其中服务器不需要监听,所以只要客户端连接,指定相应的服务器,则就可以正常交流。而交流的载体是通过DatagramPacket对象。因为DatagramPacket中包含要发送的目的地。

二:::::
     介绍:当客户端连接后,服务器会发送消息到客户端。客户端收到服务器发送来的消息,并输出。
 
     代码如下:客户端和服务器端都在本机上测试。
 
     服务器
    
[html] 
  1. package com17;  
  2. import java.io.IOException;  
  3. import java.io.PrintStream;  
  4. import java.net.ServerSocket;  
  5. import java.net.Socket;  
  6.   
  7. public class Server {  
  8.      public static void main(String[] args) {  
  9.           //创建月hi个ServerSocket,用于监听客户端Socket的连接请求  
  10.           try {  
  11.                ServerSocket ss=new ServerSocket(30000);  
  12.                //采用死循环不断接受来自客户端的请求  
  13.                while(true)  
  14.                {  
  15.                     //每当接受到客户端socket的请求,服务端也对应产生一个socket  
  16.                     Socket s=ss.accept();  
  17.                     System.out.println("IP为"+s.getInetAddress()+"连接此服务器");  
  18.                     //将Socket对应的输出流包装成PrintStream  
  19.                     PrintStream ps=new PrintStream(s.getOutputStream());  
  20.                     //进行普通的io操作  
  21.                     ps.println("客户端您好,我是服务器。");  
  22.                     ps.close();  
  23.                     s.close();           
  24.                }  
  25.           } catch (IOException e) {  
  26.                // TODO Auto-generated catch block  
  27.                e.printStackTrace();  
  28.           }  
  29.            
  30.      }  
  31.   
  32. }  

   客户端:
 
[html] 
  1. package com17;  
  2. import java.io.BufferedReader;  
  3. import java.io.IOException;  
  4. import java.io.InputStreamReader;  
  5. import java.net.Socket;  
  6.   
  7. public class Client {  
  8.      public static void main(String[] args) {  
  9.           try  
  10.           {  
  11.                Socket socket=new Socket("127.0.0.1",30000);  
  12.                //将socket对应的输入流包装成BufferedReader  
  13.                BufferedReader br=new BufferedReader( new InputStreamReader(socket.getInputStream()));  
  14.                 
  15.                //进行普通的io操作  
  16.                String line=br.readLine();  
  17.                System.out.println("来自服务器的数据::"+line);  
  18.                br.close();  
  19.                socket.close();  
  20.   
  21.           }  
  22.           catch(IOException e)  
  23.           {  
  24.                e.printStackTrace();  
  25.           }  
  26.            
  27.      }  
  28.   
  29. }  

  效果如下:
 
 
 
 
【单线程】一对一服务器1<——>1客户端 
 
 
      介绍:服务器和客户端分别接受对方发送的信息,然后再发送数据到对方。
      若是发送已经编译好的数据,则这块是很简单的。
      在第一个demo的基础上,修改服务器端的main方法:
      服务器端:
     
[html] 
  1. while( true)  
  2.   
  3.     //每当接受到客户端socket的请求,服务端也对应产生一个socket  
  4.    Socket s=ss.accept();  
  5.    System. out.println( "IP为"+s.getInetAddress()+ "连接此服务器" );  
  6.     //接受客户端发送的数据  
  7.    BufferedReader br= new BufferedReader( new InputStreamReader(s.getInputStream()));  
  8.    System. out.println( "来自客户端的数据:" +br.readLine());  
  9.     //将Socket对应的输出流包装成PrintStream  
  10.    PrintStream ps= new PrintStream(s.getOutputStream());  
  11.     //进行普通的 io操作  
  12.    ps.println( "客户端您好,我是服务器。" );  
  13.    ps.close();  
  14.    br.close();  
  15.    s.close();        

  客户端:
 
[html]
  1.  try  
  2. {  
  3.      Socket socket=new Socket("127.0.0.1",30000);  
  4.       //发送数据  
  5.      PrintStream ps= new PrintStream(socket.getOutputStream());  
  6.      ps.println( "您好,我是客户端" );  
  7.       //将socket对应的输入流包装成BufferedReader  
  8.      BufferedReader br= new BufferedReader( new InputStreamReader(socket.getInputStream()));  
  9.       //进行普通的io操作  
  10.      String line=br.readLine();  
  11.      System. out.println( "来自服务器的数据::" +line);  
  12.      br.close();  
  13.      ps.close();  
  14.       socket.close();  
  15.   
  16. }  
效果如下:
 
      注意:服务器和客户端互相发送的数据都是已经编译好的。但是通常情况下,我们发送数据,都是想发什么就发什么,所以呢,应该通过键盘输入来发送数据。
      但是通过键盘输入,需要监听用户键盘输入。这个键盘输入会有一定的问题。
      比如客户端发送数据如下:还是在上述demo的Client端基础上:
     
[html] 
  1.   //获取该socket对应的输出流  
  2. PrintStream ps= new PrintStream(s.getOutputStream());  
  3. String line= null;  
  4. //不断读取键盘的输入  
  5. BufferedReader br= new BufferedReader( new InputStreamReader(System.in));  
  6. while((line=br.readLine())!= null)  
  7. {  
  8.      //将用户的键盘输入内容写入socket对应的输出流  
  9.      ps.println(line);  
  10. }  

     
      请注意看system.in这个方法,则程序一直在死循环中,则无法执行下面的接受服务器方法。
      也许你说,那直接在循环中,发送完毕后,直接接受。
      但是这种办法,就会造成,你在dos窗口中只能发一条语句,然后,等待接受。
      那该怎么办呢?我想发送数据和我的接受数据不相关分离,并不是硬生生滴绑定在一块。

三:::::



     【多线程】一对多服务器1<——>N客户端(非聊天室的服务器通过用户输入发送数据)
      对,解决方案,就是发送数据和接受数据不在同一个进程,这样,这两个进程互不影响。
      解决方案如下:服务器端和客户端如下:
              
   
      当然,若下文要考虑,多个客户端连接同一个服务端时,所以,应该对每个sockt连接开启一个线程。但是对于客户端而言,只要把发送和接受分离即可。所以在客户端中,可以把发送数据和主进程放在一块。如下图:
     
    
        代码实现如下:
        服务器端:
      
[java]
  1.  package com17.tcp;  
  2. import java.io.IOException;  
  3. import java.net.ServerSocket;  
  4. import java.net.Socket;  
  5.   
  6.   
  7. public class MyServer {  
  8.       
  9.      public static void main(String[] args) {  
  10.           try {  
  11.                ServerSocket ss=new ServerSocket(30000);  
  12.                while(true)  
  13.                {  
  14.                     //此行代码会阻塞,将一直等待别人的连接  
  15.                     Socket s=ss.accept();  
  16.                     if(s.isConnected())  
  17.                     {  
  18.                          System.out.println("一个客户端连接此服务器"+s.getInetAddress());  
  19.                     }  
  20.                     //每当客户端连接后启动一条ServerThread线程为该客户端服务  
  21.                     new Thread( new ServerThread(s)).start();  
  22.                   //发送数据到客户端  
  23.                     new Thread(new ServerThread2(s)).start();  
  24.                }  
  25.           } catch (IOException e) {  
  26.                // TODO Auto-generated catch block  
  27.                e.printStackTrace();  
  28.           }  
  29.   
  30.      }  
  31.   
  32. }  

  
      接受数据的并打印的线程:
     
[html]
  1. package com17.tcp;  
  2. import java.io.BufferedReader;  
  3. import java.io.IOException;  
  4. import java.io.InputStreamReader;  
  5. import java.io.PrintStream;  
  6. import java.net.Socket;  
  7. import java.util.Scanner;  
  8.   
  9. public class ServerThread implements Runnable {  
  10.   
  11.      //定义当前线程所处理的socket  
  12.      Socket s=null;  
  13.      //该线程所处理的socket所对应的输入流  
  14.      BufferedReader br=null;  
  15.       
  16.      public ServerThread(Socket s)  
  17.      {  
  18.           try  
  19.           {  
  20.                this.s=s;  
  21.                //初始化socket对应的输入流  
  22.                br=new BufferedReader(new InputStreamReader(s.getInputStream()));  
  23.                 
  24.           }  
  25.           catch(IOException e)  
  26.           {  
  27.                e.printStackTrace();  
  28.           }  
  29.       
  30.      }  
  31.       
  32.      @Override  
  33.      public void run() {  
  34.   
  35.          try  
  36.          {  
  37.               String content=null;  
  38.              //采用循环不断从Socket中读取客户端发送过来的数据  
  39.              while((content=readFromClient())!=null)  
  40.              {  
  41.                   System.out.println("来自客户端消息:"+content);  
  42.              }  
  43.              System.out.println("消息:"+content);  
  44.              PrintStream ps=new PrintStream(s.getOutputStream());  
  45.              ps.println(br.readLine());  
  46.          }catch(Exception e)  
  47.          {  
  48.               try  
  49.               {  
  50.                    s.close();  
  51.               }catch(IOException ex)  
  52.               {  
  53.                    ex.printStackTrace();  
  54.               }  
  55.          }  
  56.   
  57.      }  
  58.       
  59.      //定义读取客户端数据的方法  
  60.      private String readFromClient()  
  61.      {  
  62.           try  
  63.           {  
  64.                return br.readLine();  
  65.           }  
  66.           //如果捕捉到异常,表明该socket对应的客户端已经关闭  
  67.           catch(IOException e)  
  68.           {  
  69.               e.printStackTrace();  
  70.           }  
  71.         return null;  
  72.      }  
  73. }  

   
    发送数据到客户端的线程:
    
[html] 
  1. package com17.tcp;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.IOException;  
  5. import java.io.InputStreamReader;  
  6. import java.io.PrintStream;  
  7. import java.net.Socket;  
  8.   
  9. public class ServerThread2 implements Runnable {  
  10.   
  11.      private Socket s;  
  12.      //用来处理发送数据的  
  13.      private PrintStream ps=null;  
  14.      public ServerThread2(Socket s)  
  15.      {  
  16.           try  
  17.           {  
  18.                this.s=s;  
  19.                ps=new PrintStream(s.getOutputStream());  
  20.           }  
  21.           catch(IOException e)  
  22.           {  
  23.                try  
  24.                {  
  25.                     s.close();  
  26.                }  
  27.                catch(IOException ex)  
  28.                {  
  29.                     ex.printStackTrace();  
  30.                }  
  31.                 
  32.           }  
  33.   
  34.      }  
  35.      @Override  
  36.      public void run() {  
  37.           try  
  38.           {  
  39.                  //发送数据到客户端  
  40.                   String line=null;  
  41.                    
  42.                   //不断读取键盘的输入  
  43.                   BufferedReader br=new BufferedReader(new InputStreamReader(System.in));  
  44.                   while((line=br.readLine())!=null)  
  45.                   {  
  46.                        //将用户的键盘输入内容写入socket对应的输出流  
  47.                        ps.println(line);  
  48.                   }  
  49.           }  
  50.           catch(IOException e)  
  51.           {  
  52.                e.printStackTrace();  
  53.           }  
  54.   
  55.      }  
  56.   
  57. }  

  
    客户端:
   
[html] 
  1. package com17.tcp;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.IOException;  
  5. import java.io.InputStreamReader;  
  6. import java.io.PrintStream;  
  7. import java.net.Socket;  
  8.   
  9. //负责读取用户的键盘输入,并将用户输入的数据写入socket对应的输出流中  
  10. //一条负责读取socket对应输入流中的数据(从服务器发送过来的数据)  
  11. //并将这些数据打印输出。其中负责读取用户键盘输入的线程由MyClient负责,也就是由程序的主线程负责。  
  12. public class MyClient {  
  13.   
  14.   
  15.     public static void main(String[] args) {  
  16.           
  17.         try  
  18.         {  
  19.            Socket s=new Socket("127.0.0.1",30000);  
  20.            //客户端启动clientThread县城不断读取来自服务器的数据  
  21.            new Thread(new ClientThread(s)).start();  
  22.            //获取该socket对应的输出流  
  23.            PrintStream ps=new PrintStream(s.getOutputStream());  
  24.            String line=null;  
  25.            //不断读取键盘的输入  
  26.            BufferedReader br=new BufferedReader(new InputStreamReader(System.in));  
  27.            while((line=br.readLine())!=null)  
  28.            {  
  29.                //将用户的键盘输入内容写入socket对应的输出流  
  30.                ps.println(line);  
  31.            }  
  32.         }  
  33.         catch(IOException e)  
  34.         {  
  35.             e.printStackTrace();  
  36.         }  
  37.           
  38.          
  39.     }  
  40.   
  41. }  
客户端线程:

  
[html]
  1. package com17.tcp;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.IOException;  
  5. import java.io.InputStreamReader;  
  6. import java.net.Socket;  
  7.   
  8. public class ClientThread implements Runnable {  
  9.   
  10.     //该线程负责处理的socket  
  11.     private Socket s;  
  12.     //该线程所处理的socket所对应的输入流  
  13.     BufferedReader br=null;  
  14.       
  15.     public ClientThread(Socket s) throws IOException  
  16.     {  
  17.         this.s=s;  
  18.         br=new BufferedReader(new InputStreamReader(s.getInputStream()));     
  19.     }  
  20.       
  21.     @Override  
  22.     public void run() {  
  23.           
  24.         try  
  25.         {  
  26.             String content=null;  
  27.             //不断读取socket输入流中的内容,讲这些内容打印输出  
  28.             while((content=br.readLine())!=null)  
  29.             {  
  30.                 System.out.println("来自服务器端消息:"+content);  
  31.             }  
  32.         }  
  33.         catch(IOException e)  
  34.         {  
  35.             e.printStackTrace();  
  36.         }  
  37.     }  
  38.   
  39. }  

    效果如下:
   
   
   但是我们通过以上的代码,要实现这种如下:
  
 
     虽然上述代码中使用了多线程,每个客户端请求,都会产生一个读线程和写线程。但是也不能完成上图的要求。
     为什么呢?
     主要在于写的线程。
     因为写的线程,虽然捕捉了发送的socket套接字,但是写线程中是时刻监听用户输入System.in。
     这样,当多个客户端连接服务器端时,则服务器端有多个线程监听用户输入System.in。但是令人头疼的是,服务器端只有一个dos窗口,而不像客户端一个dos窗口监听一个用户输入System.in。
      访问中服务器端结果如下:
     
      
         所以服务器想通过用户输入形式发送给多个客户端,这种形式是不可行的。
         代码中,永远只能发给具有活动的线程。结果不是你想象的那样,发给你想象的线程。
        当然,若是服务器不是通过监听用户输入则当然可以实现上述的要求的
        我们改一下服务器端:不通过监听用户输入。
        服务器端中,接受线程中,一接受到客户的数据,则发送数据。
        服务器端,线程如图:
       
      
       接受线程中修改上述的demo
      
[html] 
  1.    //采用循环不断从Socket中读取客户端发送过来的数据  
  2. while((content=readFromClient ())!=null )  
  3. {  
  4.       System. out.println( "来自客户端消息:" +content);  
  5.       ps.println( "客户端"+s.getInetAddress()+"消息已经收入到,消息为:" +content);  
  6. }  

        
        效果图如下:
      
 
   【多线程】一对多服务器1<——>N客户端(聊天室)
    
      我想通过上述几个例子,想必对通信的方式已经了解,并且也掌握通信的原理以及通信方法。
      那我们再说,聊天室通信,就是类似我们qq群。一人发表了看法,则其他的人都能看到此消息。
      猜想qq实现方式,就是通过服务器转发【仅此个人看法】
      那我们这个例子实现方式如下图:
      
    
     那这个例子 不在贴代码,我们说一下思路,在服务器端有个列表,专门用来保存客户端的socket。只要客户端连接服务器,就把客户端的socket添加到服务器列表中。当接受到任何客户端数据时,就把数据转发给列表中任何一个客户端socket。
     部分代码如下:
   

  1. //采用循环不断从Socket中读取客户端发送过来的数据  
  2. while((content=readFromClient())!= null)  
  3. {  
  4.       //便利socketList中的每一个socket  
  5.       //将读到的内容向每个socket发送一次  
  6.       for(Socket s:MyServer. socketList)  
  7.       {  
  8.            PrintStream ps= new PrintStream(s.getOutputStream());  
  9.            ps.println(content);  
  10.       }  
  11. }   
  12.  
  13. ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥ 

  14.     多线程最终服务器和客户端集成一体【swing程序】
        我们通过窗体形式来实验这个socket通信。
        窗体形式,其实把服务器和客户端集成在一起。因此每个窗体程序既是客户端又是服务器端。
        窗体应用程序思路:运行窗体后,此服务器在后台默默监听,而前端展示给客户的是我们所谓的客户端。若服务器接受到相应的消息,则反应在客户端窗体消息窗口中。
        首先脑海中窗体形式如下:
        

        为CS新手补习点图形化知识:

        Java中使用Awt和Swing类来完成图形化界面。其中Awt是abstract window tookit(抽象窗口工具库),他是最早的gui库。
        那为什么会出现swing类呢?他们两者的关联是什么呢?
        1.Awt在所有平台上展示的界面很丑陋,功能也有限。
        2.Awt是非常笨拙、非面向对象的编程方式。
        3.Awt是调用底层平台的GUI实现,因此限制了Awt支持的GUI的实现。
       而swing则:
        1.开发的图形界面要不awt优秀。
        2.采用mvc架构设计,使显示数据与数据来源隔离。
        3.是纯java开发,所以在任何平台都展示一样的效果,而不是依赖平台。
        他们之间的关联是:swing是在awt的基础上开发出来,现在很少使用awt组件,大部分使用swing组件。
       
        在AWT组件结构:
         
        容器的继承关系如下:
       
       事件关系如下:
       
       还有就是布局管理器组件了。代码中会有相应的解释。
       而swing组件关系:
       
        分析我们脑海中的窗体,差不多我们都知道布局。
        因为是Tcp协议测试,所以是基于面向链接发送数据。所以在发送之前,首先要连接服务器,若连接上,然后再发送数据。
        客户端与服务器消息交流都是在中间的消息框中展示。
        在这个窗体中,到底如何布局呢?
        这就需要awt的布局管理器。在代码中,我们用的是BorderLayout组件,布局方式是分为东南西北中,若不指定方向,则默认是中间。
           BoderLayout效果如下:
         
      
         在构造器启动服务,服务一直在监听客户端。
         若监听到,则开启接受信息的线程,其中线程类作为此主线程类的内部类。
         代码如下:并且其中有详细的注释:
        
    1. package com.test;  
    2. import java.awt.BorderLayout;  
    3. import java.awt.event.ActionEvent;  
    4. import java.awt.event.ActionListener;  
    5. import java.io.BufferedReader;  
    6. import java.io.IOException;  
    7. import java.io.InputStreamReader;  
    8. import java.io.PrintStream;  
    9. import java.net.InetAddress;  
    10. import java.net.ServerSocket;  
    11. import java.net.Socket;  
    12.   
    13. import javax.swing.JButton;  
    14. import javax.swing.JFrame;  
    15. import javax.swing.JLabel;  
    16. import javax.swing.JOptionPane;  
    17. import javax.swing.JPanel;  
    18. import javax.swing.JScrollBar;  
    19. import javax.swing.JScrollPane;  
    20. import javax.swing.JTextArea;  
    21. import javax.swing.JTextField;  
    22.   
    23.   
    24.   
    25. public class SocketTcpDemo1 extends JFrame implements ActionListener {  
    26.   
    27.      //输入的IP标签  
    28.     private JLabel ipLable;  
    29.     //输入对方的ip地址  
    30.     private JTextField sendIp;  
    31.     //连接按钮  
    32.     private JButton linkBtn;  
    33.     //发送的数据框  
    34.     private JTextField sendText;  
    35.     //显示数据显示框  
    36.     private JTextArea showMessage;  
    37.     //创建滚动条 主要是创建垂直滚动条  
    38.     private JScrollBar verscrollbar;  
    39.     //默认端口号  
    40.     private int port=30000;  
    41.     //发送按钮  
    42.     private JButton sendBtn;  
    43.     //默认发送的ip  
    44.     public String defaultSendIp="127.0.0.1";  
    45.     //连接socket  
    46.     private Socket socket;  
    47.   
    48.     //构造方法  
    49.     public SocketTcpDemo1()  
    50.     {  
    51.         this.setTitle("测试tcp通信的窗体");  
    52.         this.setBounds(200, 200, 500, 500);  
    53.         this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
    54.         this.setLayout(new BorderLayout());  
    55.           
    56.         //定义消息显示数据框  
    57.         showMessage=new JTextArea();  
    58.         //设置不可以编辑,消息显示的数据框  
    59.         showMessage.setEditable(false);  
    60.           
    61.         //消息显示数据框不够,需要添加滚动条  
    62.         JScrollPane messageScrollPane=new JScrollPane(showMessage);  
    63.         verscrollbar=messageScrollPane.createVerticalScrollBar();  
    64.         //把滚动面板放在JFrame容器中  
    65.         this.add(messageScrollPane, BorderLayout.CENTER);  
    66.           
    67.         //设置连接ip的数据框  
    68.         JPanel panel=new JPanel(new BorderLayout(5,2));  
    69.         //设置发送默认的ip  
    70.         sendIp=new JTextField(defaultSendIp);  
    71.         panel.add(sendIp,BorderLayout.CENTER);  
    72.         //连接按钮  
    73.         linkBtn=new JButton("连接");  
    74.         panel.add(linkBtn,BorderLayout.EAST);  
    75.         //ip标签显示  
    76.         ipLable =new JLabel("对方IP:");  
    77.         panel.add(ipLable,BorderLayout.WEST);  
    78.         //然后把这个panel放在Frame的上方  
    79.         this.add(panel,BorderLayout.NORTH);  
    80.           
    81.         //设置发送数据框的位置  
    82.         JPanel sendDataPanel=new JPanel(new BorderLayout(5,2));  
    83.         //发送数据文本框  
    84.         sendText=new JTextField();  
    85.         sendDataPanel.add(sendText,BorderLayout.CENTER);  
    86.         //发送按钮  
    87.         sendBtn=new JButton("发送");  
    88.         sendDataPanel.add(sendBtn,BorderLayout.EAST);  
    89.         //然后把这个panel放在Frame的下方  
    90.         this.add(sendDataPanel,BorderLayout.SOUTH);  
    91.           
    92.         //可视化  
    93.         this.setVisible(true);  
    94.         //添加事件源  
    95.         linkBtn.addActionListener(this);  
    96.         sendBtn.addActionListener(this);  
    97.         //启动监听服务方法  
    98.         TcpServer();  
    99.           
    100.           
    101.     }  
    102.     public void actionPerformed(ActionEvent e) {  
    103.           
    104.         if(linkBtn==e.getSource())  
    105.         {  
    106.             //判断是否能连接上  
    107.             try {  
    108.                 socket=new Socket(sendIp.getText().trim(),port);  
    109.                 JOptionPane.showMessageDialog(this, "连接成功");  
    110.   
    111.             } catch (Exception e1) {  
    112.                 try {  
    113.                     JOptionPane.showMessageDialog(this, "连接失败");  
    114.                     socket.close();  
    115.                 } catch (IOException e2) {  
    116.                     // TODO Auto-generated catch block  
    117.                     e2.printStackTrace();  
    118.                 }  
    119.             }  
    120.         }  
    121.         else if(sendBtn==e.getSource())  
    122.         {  
    123.             try {  
    124.                 PrintStream ps=new PrintStream(socket.getOutputStream());  
    125.                 ps.println(sendText.getText());  
    126.       
    127.                 //显示框中显示  
    128.                 showMessage.append(InetAddress.getLocalHost().getHostAddress()+"说:"+sendText.getText()+"\n");  
    129.                   
    130.   
    131.                 sendText.setText("");  
    132.             } catch (IOException e1) {  
    133.                 // TODO Auto-generated catch block  
    134.                 e1.printStackTrace();  
    135.             }  
    136.               
    137.         }  
    138.    
    139.     }  
    140.     public static void main(String[] args) {  
    141.         SocketTcpDemo1 tcpSocket=new SocketTcpDemo1();  
    142.           
    143.     }  
    144.       
    145.     //服务监听  
    146.     private void TcpServer()  
    147.     {  
    148.         try {  
    149.                 ServerSocket ss = new ServerSocket(port);  
    150.                 while(true)  
    151.                 {  
    152.                     //此行代码会阻塞,将一直等待别人的连接  
    153.                     Socket s=ss.accept();  
    154.                     new Thread(new ServerThread(s)).start();  
    155.                 }  
    156.   
    157.              }  
    158.              catch (IOException e)   
    159.              {  
    160.                e.printStackTrace();  
    161.                             
    162.              }  
    163.       }  
    164.   
    165.  class ServerThread implements Runnable {  
    166.   
    167.         //定义当前线程所处理的socket  
    168.         Socket s=null;  
    169.         //该线程所处理的socket所对应的输入流  
    170.         BufferedReader br=null;  
    171.           
    172.         public ServerThread(Socket s)  
    173.         {  
    174.             try  
    175.             {  
    176.                 this.s=s;  
    177.                 //初始化socket对应的输入流  
    178.                 br=new BufferedReader(new InputStreamReader(s.getInputStream()));  
    179.             }  
    180.             catch(IOException e)  
    181.             {  
    182.                 e.printStackTrace();  
    183.             }         
    184.         }  
    185.           
    186.         @Override  
    187.         public void run()  
    188.         {  
    189.             try {  
    190.                 String content = null;  
    191.                  while((content = br.readLine()) != null) {  
    192.                      //服务器发送的消息  
    193.                     showMessage.append(sendIp.getText().trim()+"说:" + content + "\n");  
    194.                 }  
    195.             } catch (IOException e) {  
    196.                 e.printStackTrace();  
    197.             }  
    198.               
    199.         }  
    200.     }  
    201. }  

         效果如下:
         测试连接窗体:
        
        
        互相通信窗口:
       
      至此,目录中的总结都已经整理完毕。
     
      整理这部分内容的原因:第一:socket通信,当时元旦两天测试出来,可当时遇到点问题,所以索性把练习之旅记录下来。第二:练习基础中的多线程,多线程这部分,基本上理论都可以讲出来,但是项目中一直没有用到。第三:初次接触图形化界面,因为这方面内容没有涉及到,大部分是在研究web方向,但是就像揭开他的神秘面纱。
       呵呵,基于以上原因,才有了此次总结的想法。最近一直在研究其他的东西,所以博客没有及时贴出来。(*^__^*)嘻嘻
      
        编译打包成jar包,这部分内容暂时不更新博客了。其实,在打包的过程中应用了ant打包。对于ant的应用,我们有时间再更新博客。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值