[Java] Java Socket编程范例

socket用中文意思就是我们常说的”套接字“,我们用它来解决基于TCP/IP协议的网络通信。Java有一套功能强大而又易于使用的网络开发API,这个API是一系列的接口和类,在java.net和javax.net包中可以找到它们。套接字一般分为两种:流套接字(StreamSocket)和数据报套接字(DatagramSockets)。关于套接字的编程可以写成一本书,本文不想在这里做深入探究(其实是本人功力还不够,嘿嘿...),这次主要是了解一下流套接字的基本开发。

一、几个重要的API
1、InetAddress类
描述
:该类在套接字编程中份演着目的地角色,通常作为参数传递给流套接字类和数据报套接字的构造方法或其它方法。
 
构造方法:该类只有一个默认的不带参的构造方法。
不能直接用new创建一个InetAddress对象。象这样做 
      InetAddressia = new InetAddress ();
就是错误的。但是我们可以通过它的5个静态工厂方法获得一个InetAddress对象或对象数组。
 
重要方法:
        staticInetAddress[] getAllByName(Stringhost);
      通过传递参数host(主机名),返回一个InetAddress对象数组的引用。如果指定的主机没有IP地址存在,则方法抛出一个UnknownHostException异常对象。
        staticInetAddress getByAddress(byte[]addr);
      通过传递一个用字节数组表示的二进制IP地址参数(4字节对应Ipv4,16字节对应Ipv6),返回一个InetAddress对象的引用。如果返回对象的数组既不是4字节也不是16字节,则方法抛出一个UnknownHostException异常对象。
        staticInetAddress getByAddress(String host, byte[]addr);
      创建一个基于给定主机名和给定字节数组组成的IP地址的InetAddress对象。如果返回对象中的数组既不是4字节也不是16字节,则方法抛出一个UnknownHostException异常对象。
        staticInetAddress getByName(Stringhost);
      返回一个与给定主机名的InetAddress对象。如果指定的主机没有IP对应,则方法抛出一个UnknownHostException异常对象。
        staticInetAddressgetLocalHost();
      返回一个包含本地主机的IP地址的InetAddress对象。
       
      上面讲到的方法均提到返回一个或多个InetAddress对象的引用,实际上每一个方法都要返回一个或多个Inet4Address/Inet6Address对象的引用。一旦获得了InetAddress对象,你就可以使用其他非静态方法得到你想要的东东了。
 
2、Socket类
描述:Socket是建立网络连接时使用的。在连接成功时,服务端和客户端都会产生一个Socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。
 
构造方法:该类有多个构造方法,常用的有两个: Socket(InetAddressaddr, intport) 和  Socket(Stringhost, intport)
      两个构造方法都创建了一个基于指定接服务器主机名或InetAddress和服务器端口号的流套接字。对于第一个InetAddress子类对象通过addr参数获得服务器主机的IP地址,对于第二个函数host参数包被分配到InetAddress对象中,如果没有IP地址与host参数相一致,那么将抛出UnknownHostException异常对象。
      如果创建连接成功,java网络API将在客户端的流套接字中捆绑客户程序的IP地址和任意一个端口号,否则两个函数都会抛出一个IOException对象。
 
重要方法:
        InputStreamgetInputStream();
      获得网络连接输入,同时返回一个IutputStream对象实例。
        OutputStreamgetOutputStream();
      获得网络连接输出,连接的另一端将得到输入,同时返回一个OutputStream对象实例。
      必须捕获两个方法可能产生的IOException。怎么操作这些流对象就看你要作什么了!:)
 
3、ServerSocket类
描述:
该类用于服务器端。
构造方法:该类有四个构造方法,常用的有:
        ServerSocket(intport)
      通过指定监听端口号来创建ServerSocket对象,如果在这时出现错误将抛出IOException异常对象,否则将创建ServerSocket对象并开始准备接收连接请求。接下来无限循环调用accept()方法。
 
重要方法:
        Socketaccept();
      调用开始后accept()方法将导致调用线程阻塞直到连接建立。在建立连接后accept()返回一个最近创建的Socket对象,该Socket对象绑定了客户程序的IP地址和端口号。
 
4、注意事项:
      在服务端和客户端均未发送数据时,不要在同时在两端的while()循环里读取 InputStream。否则将造成阻塞。
      如果用字符流处理数据,请在数据末尾加上“ \r\n”,并记得  flush()一下。
 
二、实例
1、 服务端 SimpleServerSocket:

      例子采用字节流来操作,注释部分是采用字符流来操作。
java 代码
  1. package com.unihub.unicall.test;  
  2.   
  3. import java.io.IOException;  
  4. import java.net.ServerSocket;  
  5.   
  6. public class SocketServerTest  
  7.     private ServerSocket server null 
  8.      private int port 9999 
  9.      public SocketServerTest() throws IOException   
  10.       
  11.       int counter 1 
  12.       try   
  13.        
  14.        this.server new ServerSocket(this.port);  
  15.         
  16.       catch (Exception ex)   
  17.        
  18.        System.err.println("Can't listening on port:" this.port);  
  19.        ex.printStackTrace(System.err);  
  20.        System.exit(-1);  
  21.        
  22.       System.out.println("Start listening on port:" this.port);  
  23.       while (true  
  24.        
  25.        new ServerThread(server.accept(),counter).start();  
  26.        counter++;  
  27.        
  28.       
  29.      public static void main(String[] args) throws Exception   
  30.       
  31. //       SocketServerTest sserver    
  32.              new SocketServerTest();  
  33.       
  34.   
  35.  

线程类:

java 代码
  1. package com.unihub.unicall.test;  
  2.   
  3. import java.io.BufferedInputStream;  
  4. import java.io.BufferedOutputStream;  
  5. import java.io.IOException;  
  6. import java.net.Socket;  
  7.   
  8. import com.unihub.unicall.common.util.SocketUtil;  
  9.   
  10. public class ServerThread extends Thread  
  11.     private Socket client;  
  12.   
  13.     private int counter;  
  14.   
  15.     public ServerThread(Socket client, int counter)  
  16.         System.out.println("[info] Create connection with "  
  17.                 client.getInetAddress().getHostAddress().toString()  
  18.                 successful.");   
  19.         this.client client;  
  20.         this.counter counter;  
  21.      
  22.   
  23.     public void run()  
  24.         try  
  25.             BufferedInputStream bis new BufferedInputStream(client  
  26.                     .getInputStream());  
  27.             BufferedOutputStream bos new BufferedOutputStream(client  
  28.                     .getOutputStream());  
  29.             // BufferedReader in new BufferedReader(new   
  30.             // InputStreamReader(client.getInputStream()));   
  31.             // PrintWriter out new PrintWriter(client.getOutputStream(),true);   
  32.   
  33.             bos.write(("Hi! Enter QUIT to exit.\r\n").getBytes());  
  34.             bos.flush();  
  35.   
  36.             boolean done false 
  37.             byte[] bytes new byte[client.getReceiveBufferSize()];  
  38.             while (!done)  
  39.                 int contentLength bis.read(bytes);  
  40.   
  41.                 if (contentLength == -1 
  42.                     System.out.println("contentLength " contentLength);  
  43.                     done true 
  44.                 else  
  45. //                  String recieve new String(bytes, 0, contentLength);   
  46. //                  if (recieve.trim().equalsIgnoreCase("quit"))   
  47. //                      done true;   
  48. //                  else   
  49. //                      System.out.println("[info] recieve);   
  50. //   
  51. //                      bos   
  52. //                              .write(("Echo server(" counter "):"   
  53. //                                      recieve "\r\n").getBytes());   
  54. //                      bos.flush();   
  55. //                    
  56.                     byte[] b1 SocketUtil.getSubByte(bytes, 04);  
  57.                     byte[] b2 SocketUtil.getSubByte(bytes, 44);  
  58.                     byte[] b3 SocketUtil.getSubByte(bytes, 20257);  
  59.                     System.out.println("111111111111:"+SocketUtil.byte2int(b1));  
  60.                     System.out.println("报文长度:"+SocketUtil.byte2int(b2));  
  61.                     System.out.println("报文内容:"+new String(b3,"ISO-8859-1"));  
  62.                  
  63.              
  64.               
  65.             // String recieve;   
  66.             // while((recieve in.readLine()) != null)   
  67.             //   
  68.             // if(recieve.trim().equalsIgnoreCase("quit")){break;}   
  69.             // else   
  70.             //   
  71.             // System.out.println("[info] recieve);   
  72.             // out.println("Echo server("+ counter +"):" recieve);   
  73.             //   
  74.             //   
  75.         catch (Exception e)  
  76.             e.printStackTrace();  
  77.         finally  
  78.             try  
  79.                 if (client != null 
  80.                     client.close();  
  81.                     System.out.println("[info] Disconnect successful.");  
  82.                  
  83.             catch (IOException e1)  
  84.                 e1.printStackTrace();  
  85.              
  86.          
  87.      
  88.   
  89.  

2、 客户端 SimpleSocket:

java 代码
  1. package com.cyberobject.socket;  
  2.    
  3. import java.io.*;  
  4. import java.net.*;  
  5.   
  6. public class SimpleSocket   
  7.   
  8.  private Socket client;  
  9.  private String host "192.168.0.66";   
  10.  private int port 30000 
  11.    
  12.  public SimpleSocket()    
  13.     
  14.   try   
  15.    
  16.    this.client new Socket(InetAddress.getByName(this.host),this.port);  
  17.        
  18.    System.out.println("[info] Connect to " this.host successful.");   
  19.    
  20. //          BufferedReader in new BufferedReader(new   
  21. //          InputStreamReader(client.getInputStream()));   
  22. //          PrintWriter out new PrintWriter(client.getOutputStream(),true);   
  23.    BufferedReader systemIn new BufferedReader(new InputStreamReader(System.in));  
  24.       
  25.     BufferedInputStream bis new BufferedInputStream(client.getInputStream());  
  26.    BufferedOutputStream bos new BufferedOutputStream(client.getOutputStream());  
  27.    
  28.    System.out.println("[info] Start...");  
  29.    
  30.   boolean done false 
  31. //              while(!done)   
  32. //                
  33. //               String recieve in.readLine();   
  34. //               if(recieve == null) done true;   
  35. //               else   
  36. //                 
  37. //                System.out.println(recieve);   
  38. //                out.println(systemIn.readLine());   
  39. //                 
  40. //                
  41.    
  42.    byte[] bytes new byte[client.getReceiveBufferSize()];  
  43.    int len 0 
  44.    while (!done)  
  45.      
  46.     len bis.read(bytes);  
  47.     if (len == -1done true 
  48.     else   
  49.          
  50.      String recieve new String(bytes, 0len);  
  51.         
  52.       System.out.println(recieve);  
  53.      bos.write(systemIn.readLine().getBytes());  
  54.      bos.flush();  
  55.      
  56.     
  57.      
  58.    System.out.println("[info] Stop.");   
  59.       
  60.   catch (Exception ex)   
  61.    
  62.    ex.printStackTrace(System.err);  
  63.     
  64.   finally   
  65.    
  66.    try  
  67.     
  68.     if (client != null  
  69.      
  70.      client.close();  
  71.      
  72.      
  73.    catch (IOException e)   
  74.     
  75.     e.printStackTrace();  
  76.     
  77.    
  78.   
  79.    
  80.  public static void main(String[] args)   
  81.   
  82.   SimpleSocket ssocket new SimpleSocket();  
  83.   
  84.  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值