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 }

 

posted @ 2018-10-22 16:17  ssc在路上  阅读(1091)  评论(0编辑  收藏  举报