zoukankan      html  css  js  c++  java
  • socket编程(Java实现)

      主要是前段时间学习的网络知识的基于TCP与UDP编程,Java实现简单的大小写字母的转化,该文主要参考:

    https://blog.csdn.net/yjp19871013/article/details/53537398

    UDP服务端代码:

     1 public class ToUpperUDPServer {
     2 
     3     //服务器的IP
     4     public static final String SERVER_IP = "127.0.0.1";
     5     
     6     //服务器端的端口号 最好是大于2000 不要选取那些特殊的端口号 Oracle:1521 MySQL:3306 Tomcat:8080
     7     public static final int SERVER_PORT = 10005;
     8     
     9     //最大的传输字节数
    10     public static final int MAX_BYTES = 1024;
    11     
    12     //UDP使用DatagramSocket发送数据包
    13     private DatagramSocket serverSocket;
    14     
    15     /**
    16      * 启动服务器
    17      * @param serverIp 服务器的IP地址
    18      * @param serverPort 服务器的端口号
    19      */
    20     public void startServer(String serverIp, int serverPort){
    21         
    22         try {
    23             //创建DatagramSocket
    24             InetAddress serverAddr = InetAddress.getByName(serverIp);
    25             serverSocket = new DatagramSocket(serverPort, serverAddr);
    26             
    27             //创建接受服务的对象
    28             byte[] recvBuf = new byte[MAX_BYTES];
    29             DatagramPacket recvPacket = new DatagramPacket(recvBuf, recvBuf.length);
    30             
    31             //死循环,一直运行服务器
    32             while(true){
    33                 
    34                 System.out.println("服务端正在接收数据,接收的数据包为:"+recvPacket);
    35                 //接受数据,会在这里堵塞,直达数据到来
    36                 serverSocket.receive(recvPacket);
    37                 String receStr = new String(recvPacket.getData(), 0 , recvPacket.getLength());
    38                 
    39                 //获取连接端的IP和端口号port
    40                 InetAddress clientAddr = recvPacket.getAddress();
    41                 int clientPort = recvPacket.getPort();
    42                 
    43                 //回传数据
    44                 String upperStr = receStr.toUpperCase();
    45                 byte[] sendBuf = upperStr.getBytes();
    46                 DatagramPacket sendPacket = new DatagramPacket(sendBuf, sendBuf.length, clientAddr, clientPort);
    47                 
    48                 System.out.println("服务端正在发送数据,发送的数据包为:"+sendPacket);
    49                 //服务器Socket 发送数据
    50                 serverSocket.send(sendPacket);
    51             }
    52             
    53         } catch (UnknownHostException e) {
    54             // TODO Auto-generated catch block
    55             e.printStackTrace();
    56         } catch (SocketException e) {
    57             // TODO Auto-generated catch block
    58             e.printStackTrace();
    59         } catch (IOException e) {
    60             // TODO Auto-generated catch block
    61             e.printStackTrace();
    62         }
    63     }
    64     
    65     public static void main(String[] args) {
    66         ToUpperUDPServer server = new ToUpperUDPServer();
    67         server.startServer(SERVER_IP, SERVER_PORT);
    68     }
    69 }

    UDP客户端代码:

     1 public class ToUpperUDPClient {
     2 
     3     //创建连接的DatagramSocket
     4     private DatagramSocket clientSocket;
     5     
     6     public String toUpperRemote(String serverIp, int serverPort, String str){
     7         
     8         String recvStr = "";
     9         
    10         try {
    11             //创建 UDP socket
    12             clientSocket = new DatagramSocket();
    13             
    14             byte[] sendBuf = str.getBytes();
    15             InetAddress serverAddr = InetAddress.getByName(serverIp);
    16             DatagramPacket sendPacket = new DatagramPacket(sendBuf, sendBuf.length, serverAddr, serverPort);
    17             clientSocket.send(sendPacket);
    18             System.out.println("客户端正在发送数据,发送的数据包为:" + sendPacket);
    19             
    20             //接收服务器的响应
    21             byte[] recvBuf = new byte[ToUpperUDPServer.MAX_BYTES];
    22             DatagramPacket recvPacket = new DatagramPacket(recvBuf, recvBuf.length);
    23             clientSocket.receive(recvPacket);
    24             System.out.println("客户端正在接收服务器的响应,接收的数据包为:" + recvPacket);
    25             
    26             //显示响应
    27             recvStr = new String(recvPacket.getData(), 0 , recvPacket.getLength());
    28             
    29         } catch (SocketException e) {
    30             // TODO Auto-generated catch block
    31             e.printStackTrace();
    32         } catch (UnknownHostException e) {
    33             // TODO Auto-generated catch block
    34             e.printStackTrace();
    35         } catch (IOException e) {
    36             // TODO Auto-generated catch block
    37             e.printStackTrace();
    38         }finally{
    39             if(null != clientSocket){
    40                 clientSocket.close();
    41                 clientSocket = null;
    42             }
    43         }
    44         return recvStr;
    45     }
    46     
    47     public static void main(String[] args) {
    48         
    49         ToUpperUDPClient client = new ToUpperUDPClient();        
    50         String recvStr = client.toUpperRemote(ToUpperUDPServer.SERVER_IP, ToUpperUDPServer.SERVER_PORT, "aaaAAAbbbBBBcccCCC");        
    51         System.out.println("客户端收到的数据:" + recvStr);
    52     }
    53 }

    TCP服务端有三种模式:

    1、基于TCP协议阻塞式服务

     1 public class ToUpperTCPBlockServer {
     2 
     3     //服务端的IP地址
     4     public static final String SERVER_IP = "127.0.0.1";
     5     
     6     //服务端的端口号
     7     public static final int SERVER_PORT = 10005;
     8     
     9     //请求终结字符串
    10     public static final char REQUEST_END_CHAR = '#';
    11     
    12     /***
    13      * 开启服务
    14      * @param serverIp 服务端ip地址
    15      * @param serverPort 服务端端口号
    16      */
    17     public void startServer(String serverIp, int serverPort){
    18         
    19         
    20         try {
    21             //创建服务器地址对象
    22             InetAddress serverAddr = InetAddress.getByName(serverIp);
    23             
    24             //Java提供了ServerSocket作为服务器
    25             //楼主使用了Java的自动关闭的语法, 这个自动关闭语法是JDK1.7中的,我这里是正常写法
    26             ServerSocket serverSocket = new ServerSocket(SERVER_PORT, 5, serverAddr);
    27             
    28             while(true){
    29                 
    30                 StringBuilder recvStrBuilder = new StringBuilder();
    31                 
    32                 //有客户端向服务器发起tcp连接时,accept会返回一个Socket
    33                 //该Socket的対端就是客户端的Socket
    34                 //具体过程可以查看TCP三次握手过程
    35                 Socket connection = serverSocket.accept();
    36                 InputStream in = connection.getInputStream();
    37                 
    38                 //读取客户端的请求字符串,请求字符以#结尾
    39                 for(int c=in.read(); c!=REQUEST_END_CHAR; c=in.read()){
    40                     recvStrBuilder.append((char) c);
    41                 }
    42                 recvStrBuilder.append("#");
    43                 String recvStr = recvStrBuilder.toString();
    44                 
    45                 //向客户端写出处理过的字符串
    46                 OutputStream os = connection.getOutputStream();
    47                 os.write(recvStr.toUpperCase().getBytes());
    48             }
    49             
    50         } catch (UnknownHostException e) {
    51             // TODO Auto-generated catch block
    52             e.printStackTrace();
    53         } catch (IOException e) {
    54             // TODO Auto-generated catch block
    55             e.printStackTrace();
    56         }
    57     }
    58     
    59     public static void main(String[] args) {
    60         ToUpperTCPBlockServer server = new ToUpperTCPBlockServer();
    61         System.out.println("服务器端开始接收请求...");
    62         server.startServer(SERVER_IP, SERVER_PORT);
    63     }
    64 }

    2、基于TCP的并发服务器 

     1 public class ToUpperTCPThreadServer {
     2     
     3     //服务器对外的ip
     4     public static final String SERVER_IP = "127.0.0.1";
     5     
     6     //服务器端口号
     7     public static final int SERVER_PORT = 10005;
     8     
     9     //请求中介字符串
    10     public static final char REQUEST_END_CHAR = '#';
    11     
    12     /***
    13      * 开启服务
    14      * @param serverIp 服务端ip
    15      * @param serverPort 服务端端口号
    16      */
    17     public void startServer(String serverIp, int serverPort){
    18         
    19         try {
    20             InetAddress serverAddr = InetAddress.getByName(serverIp);
    21             ServerSocket serverScoket = new ServerSocket(SERVER_PORT, 5 ,serverAddr);
    22             
    23             //创建线程池
    24             Executor executor = Executors.newFixedThreadPool(100);
    25             
    26             //保持服务一直处于开启的状态
    27             while(true){
    28                 final StringBuilder recvStrBuilder = new StringBuilder();
    29                 
    30                 //有客户向服务器发起TCP连接时,accept会返回一个socket
    31                 //该socket的对端就是客户端的socket
    32                 //具体情况可以查看socket的三次握手情况
    33                 final Socket connection = serverScoket.accept();
    34                 
    35                 //利用线程池,启动线程
    36                 executor.execute(new Runnable() {
    37                     
    38                     @Override
    39                     public void run() {
    40                         // TODO Auto-generated method stub
    41                         Socket conn = connection;
    42                         try {
    43                             InputStream in = conn.getInputStream();
    44                             for(int c=in.read(); c!=REQUEST_END_CHAR; c=in.read()){
    45                                 recvStrBuilder.append((char) c);
    46                             }
    47                             recvStrBuilder.append('#');
    48                             String resvStr = recvStrBuilder.toString();
    49                             
    50                             ////向客户端写出处理后的字符串
    51                             OutputStream os = connection.getOutputStream();
    52                             os.write(resvStr.toUpperCase().getBytes());
    53                             
    54                         } catch (IOException e) {
    55                             // TODO Auto-generated catch block
    56                             e.printStackTrace();
    57                         } finally {
    58                             if(conn != null){
    59                                 try {
    60                                     conn.close();
    61                                 } catch (IOException e) {
    62                                     // TODO Auto-generated catch block
    63                                     e.printStackTrace();
    64                                 }
    65                             }
    66                         }
    67                     }
    68                 });
    69             }
    70             
    71         } catch (UnknownHostException e) {
    72             // TODO Auto-generated catch block
    73             e.printStackTrace();
    74         } catch (IOException e) {
    75             // TODO Auto-generated catch block
    76             e.printStackTrace();
    77         }
    78     }
    79     
    80     public static void main(String[] args) {
    81         ToUpperTCPThreadServer server = new ToUpperTCPThreadServer();
    82         server.startServer(SERVER_IP, SERVER_PORT);
    83     }
    84 }

    3、第三种

      1 public class ToUpperTCPNonBlockServer {
      2 
      3     //服务器对外的ip
      4     public static final String SERVER_IP = "127.0.0.1";
      5     
      6     //服务器端口号
      7     public static final int SERVER_PORT = 10005;
      8     
      9     //请求中介字符串
     10     public static final char REQUEST_END_CHAR = '#';
     11     
     12     /**
     13      * 开启服务
     14      * @param serverIp 服务器对外的ip
     15      * @param serverPort 服务器端端口号
     16      */
     17     public void startServer(String serverIp, int serverPort){
     18         
     19         try {
     20             //使用NIO 需要用到ServerSocketChannel 其中包含一个serverSocket对象
     21             ServerSocketChannel serverChannel = ServerSocketChannel.open();
     22             //创建地址对象
     23             InetSocketAddress localAddr = new InetSocketAddress(SERVER_IP,SERVER_PORT); 
     24             //服务器绑定地址
     25             serverChannel.bind(localAddr);
     26             //设置为非堵塞
     27             serverChannel.configureBlocking(false);
     28             
     29             //注册到Selector 会ServerSocket的accept
     30             //我们用Selector监听accept是否返回
     31             //当调用accept卡伊返回时,会得到通知
     32             //注意是可以返回,还需要调用accept
     33             Selector selector = Selector.open();
     34             serverChannel.register(selector, SelectionKey.OP_ACCEPT);
     35             
     36             //服务一直处于启动状态,所以这个是死循环
     37             while(true){
     38                 //调用select,阻塞在这里,直到有注册的channel满足条件
     39                 selector.select();
     40                 
     41                 //如果走到这里,有符合条件的channel
     42                 //可以通过selector.selectedKeys().iterator()得到符合条件的迭代器
     43                 Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
     44                 
     45                 //处理得到的keys
     46                 while(keys.hasNext()){
     47                     
     48                     //取出一个key 并移除
     49                     SelectionKey key = keys.next();
     50                     keys.remove();
     51                     try{
     52                         if(key.isAcceptable()){
     53                             //有accept返回,取出可以使用的channel
     54                             ServerSocketChannel server = (ServerSocketChannel) key.channel();
     55                             
     56                             //调用accept三次握手 返回与客户端可以通信的channel
     57                             SocketChannel channel = server.accept();
     58                             
     59                             //将该channel 置为非堵塞
     60                             channel.configureBlocking(false);
     61                             
     62                             //注册此selector 当可读或可写时将得到通知,select返回
     63                             channel.register(selector, SelectionKey.OP_READ);
     64                         }else if(key.isReadable()){
     65                             //有channel可读  取出可读的channel
     66                             SocketChannel channel = (SocketChannel) key.channel();
     67                             
     68                             //创建读取缓冲区,一次读取1024字节
     69                             ByteBuffer buffer = ByteBuffer.allocate(1024);
     70                             channel.read(buffer);
     71                             
     72                             //锁住缓冲区,缓冲区的大小将固定
     73                             buffer.flip();
     74                             
     75                             //附件上buffer 供写出使用
     76                             key.attach(buffer);
     77                             key.interestOps(SelectionKey.OP_WRITE);
     78                         }else if(key.isWritable()){
     79                             //有channel可写,取出可写的channel
     80                             SocketChannel channel = (SocketChannel) key.channel();
     81                             
     82                             //取出可读时设置的缓冲区
     83                             ByteBuffer buffer = (ByteBuffer) key.attachment();
     84                             
     85                             //将缓冲区的指针移动到缓冲区开始的位置
     86                             buffer.rewind();
     87                             
     88                             //读取为String
     89                             String recv = new String(buffer.array());
     90                             
     91                             //清空缓冲区
     92                             buffer.clear();
     93                             buffer.flip();
     94                             
     95                             //写回数据
     96                             byte[] sendByte = recv.toUpperCase().getBytes();
     97                             channel.write(ByteBuffer.wrap(sendByte));
     98                             
     99                             //变为等待者
    100                             key.interestOps(SelectionKey.OP_READ);
    101                         }
    102                     }catch(Exception e){
    103                         key.cancel();
    104                         key.channel().close();
    105                         e.printStackTrace();
    106                     }
    107                 }
    108             }
    109         } catch (IOException e) {
    110             // TODO Auto-generated catch block
    111             e.printStackTrace();
    112         }
    113     }
    114     
    115     public static void main (String[] args){
    116         ToUpperTCPBlockServer server = new ToUpperTCPBlockServer();
    117         server.startServer(SERVER_IP, SERVER_PORT);
    118     }
    119 }

    TCP客户端:

     1 public class ToUpperTCPClient {
     2     
     3     //客户端的请求的 TCP socket
     4     private Socket clientSocket;
     5     
     6     public String toUpperRemote(String serverIp, int ServerPort, String str){
     7         
     8         StringBuilder recvStrBuilder = new StringBuilder();
     9         
    10         try {
    11             //创建连接服务器的socket
    12             clientSocket = new Socket(serverIp, ServerPort);
    13             
    14             //写出请求的字符串
    15             OutputStream os = clientSocket.getOutputStream();
    16             os.write(str.getBytes());
    17             
    18             //读取服务器响应
    19             InputStream in = clientSocket.getInputStream();
    20             for(int c=in.read(); c!='#'; c=in.read()){
    21                 recvStrBuilder.append((char) c);
    22             }
    23             
    24         } catch (UnknownHostException e) {
    25             // TODO Auto-generated catch block
    26             e.printStackTrace();
    27         } catch (IOException e) {
    28             // TODO Auto-generated catch block
    29             e.printStackTrace();
    30         }finally{
    31             if(clientSocket != null){
    32                 try {
    33                     clientSocket.close();
    34                 } catch (IOException e) {
    35                     // TODO Auto-generated catch block
    36                     e.printStackTrace();
    37                 }
    38             }
    39         }
    40         return recvStrBuilder.toString();
    41     }
    42     
    43     public static void main(String[] args) {
    44         ToUpperTCPClient client = new ToUpperTCPClient();        
    45         String recvStr = client.toUpperRemote(ToUpperTCPBlockServer.SERVER_IP, ToUpperTCPBlockServer.SERVER_PORT,"aaaAAAbbbBBBcccCCC" + ToUpperTCPBlockServer.REQUEST_END_CHAR);        
    46         System.out.println("收到:" + recvStr);
    47     }
    48 }
  • 相关阅读:
    ShopNum1网店系统:组建电子商务运营团队
    jquery 日期+时间 date & time 插件
    写代码如坐禅:你是哪一类程序员
    杨卫华:新浪微博的架构发展历程
    win7 搜索 在新窗口【打开文件位置】
    架构师应该了解的知识1
    flash cs4 和 flex builder 联合开发
    Div拖动/调整大小实例
    asp.net mvc 2.o 中使用JQuery.uploadify
    jquery 拖动改变div 容器大小
  • 原文地址:https://www.cnblogs.com/ssh-html/p/9830736.html
Copyright © 2011-2022 走看看