SSL客户端向服务端发送消息

本文出处:http://bbs.csdn.net/topics/280020824

http://blog.chinaunix.net/u/10295/showart.php?id=470055

这里有服务端客户端的源代码,不过是在linux下的 
C/C++ code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
客户端源代码如下:
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <resolv.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
 
#define MAXBUF 1024
 
void  ShowCerts(SSL * ssl)
{
     X509 *cert;
     char  *line;
 
     cert = SSL_get_peer_certificate(ssl);
     if  (cert != NULL) {
         printf ( "数字证书信息:\n" );
         line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
         printf ( "证书: %s\n" , line);
         free (line);
         line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
         printf ( "颁发者: %s\n" , line);
         free (line);
         X509_free(cert);
     else
         printf ( "无证书信息!\n" );
}
/************关于本文档********************************************
*filename: ssl-client.c
*purpose: 演示利用 OpenSSL 库进行基于 IP层的 SSL 加密通讯的方法,这是客户端例子
*wrote by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com)
Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言
*date time:2007-02-02 20:10
*Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
* 但请遵循GPL
*Thanks to:Google
*Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力
* 科技站在巨人的肩膀上进步更快!感谢有开源前辈的贡献!
*********************************************************************/
int  main( int  argc,  char  **argv)
{
     int  sockfd, len;
     struct  sockaddr_in dest;
     char  buffer[MAXBUF + 1];
     SSL_CTX *ctx;
     SSL *ssl;
 
     if  (argc != 3) {
         printf
             ( "参数格式错误!正确用法如下:\n\t\t%s IP地址 端口\n\t比如:\t%s 127.0.0.1 80\n此程序用来从某个 IP 地址的服务器某个端口接收最多 MAXBUF 个字节的消息" ,
              argv[0], argv[0]);
         exit (0);
     }
 
     /* SSL 库初始化,参看 ssl-server.c 代码 */
     SSL_library_init();
     OpenSSL_add_all_algorithms();
     SSL_load_error_strings();
     ctx = SSL_CTX_new(SSLv23_client_method());
     if  (ctx == NULL) {
         ERR_print_errors_fp(stdout);
         exit (1);
     }
 
     /* 创建一个 socket 用于 tcp 通信 */
     if  ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
         perror ( "Socket" );
         exit ( errno );
     }
     printf ( "socket created\n" );
 
     /* 初始化服务器端(对方)的地址和端口信息 */
     bzero(&dest,  sizeof (dest));
     dest.sin_family = AF_INET;
     dest.sin_port = htons( atoi (argv[2]));
     if  (inet_aton(argv[1], ( struct  in_addr *) &dest.sin_addr.s_addr) == 0) {
         perror (argv[1]);
         exit ( errno );
     }
     printf ( "address created\n" );
 
     /* 连接服务器 */
     if  (connect(sockfd, ( struct  sockaddr *) &dest,  sizeof (dest)) != 0) {
         perror ( "Connect " );
         exit ( errno );
     }
     printf ( "server connected\n" );
 
     /* 基于 ctx 产生一个新的 SSL */
     ssl = SSL_new(ctx);
     SSL_set_fd(ssl, sockfd);
     /* 建立 SSL 连接 */
     if  (SSL_connect(ssl) == -1)
         ERR_print_errors_fp(stderr);
     else  {
         printf ( "Connected with %s encryption\n" , SSL_get_cipher(ssl));
         ShowCerts(ssl);
     }
 
     /* 接收对方发过来的消息,最多接收 MAXBUF 个字节 */
     bzero(buffer, MAXBUF + 1);
     /* 接收服务器来的消息 */
     len = SSL_read(ssl, buffer, MAXBUF);
     if  (len > 0)
         printf ( "接收消息成功:'%s',共%d个字节的数据\n" ,
                buffer, len);
     else  {
         printf
             ( "消息接收失败!错误代码是%d,错误信息是'%s'\n" ,
              errno strerror ( errno ));
         goto  finish;
     }
     bzero(buffer, MAXBUF + 1);
     strcpy (buffer,  "from client->server" );
     /* 发消息给服务器 */
     len = SSL_write(ssl, buffer,  strlen (buffer));
     if  (len < 0)
         printf
             ( "消息'%s'发送失败!错误代码是%d,错误信息是'%s'\n" ,
              buffer,  errno strerror ( errno ));
     else
         printf ( "消息'%s'发送成功,共发送了%d个字节!\n" ,
                buffer, len);
 
   finish:
     /* 关闭连接 */
     SSL_shutdown(ssl);
     SSL_free(ssl);
     close(sockfd);
     SSL_CTX_free(ctx);
     return  0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,可以的。不过在整合Netty和Spring Boot之前,我们需要先了解一下RPC的概念和原理。 RPC,全称为Remote Procedure Call,即远程过程调用。它的作用是让分布式系统中的不同节点之间能够像本地调用一样,通过网络调用远程节点的方法或函数,从而实现节点之间的数据交互和通信。 在RPC中,通常会有一个服务提供者和一个服务消费者。服务提供者会将自己的方法或函数暴露出来,供服务消费者调用。服务消费者则会通过网络向服务提供者发送请求,获取响应结果。 在进行RPC调用时,服务提供者和服务消费者之间需要进行相互校验,以确保双方都是可信的。常用的校验方式包括基于Token的认证和基于SSL的加密通信。 接下来,我们可以通过Netty来实现客户端服务端之间的通信。具体实现方式如下: 1. 在Spring Boot项目中引入Netty的依赖,例如: ```xml <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.36.Final</version> </dependency> ``` 2. 实现服务提供者和服务消费者的代码逻辑,在其中包含RPC校验的逻辑。 3. 在服务提供者中,创建Netty的ServerBootstrap对象,并设置相关参数,例如: ```java ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(new NioEventLoopGroup()) .channel(NioServerSocketChannel.class) .localAddress(new InetSocketAddress(port)) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new RpcDecoder(RpcRequest.class), new RpcEncoder(RpcResponse.class), new RpcHandler()); } }); ChannelFuture future = bootstrap.bind().sync(); future.channel().closeFuture().sync(); ``` 其中,RpcDecoder和RpcEncoder用于将RPC请求和响应对象转换为字节数组,RpcHandler用于处理RPC请求,并返回响应结果。 4. 在服务消费者中,创建Netty的Bootstrap对象,并设置相关参数,例如: ```java Bootstrap bootstrap = new Bootstrap(); bootstrap.group(new NioEventLoopGroup()) .channel(NioSocketChannel.class) .remoteAddress(new InetSocketAddress(host, port)) .handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new RpcEncoder(RpcRequest.class), new RpcDecoder(RpcResponse.class), new RpcProxyHandler()); } }); RpcProxyHandler rpcProxyHandler = bootstrap.connect().sync().channel().pipeline().get(RpcProxyHandler.class); ``` 其中,RpcProxyHandler用于发送RPC请求,并返回响应结果。 5. 最后,在服务消费者中调用服务提供者的方法即可,例如: ```java HelloService helloService = rpcProxyHandler.create(HelloService.class); String result = helloService.sayHello("world"); ``` 这样,我们就可以通过Spring Boot和Netty实现RPC调用和网络通信了。需要注意的是,在实际应用中,我们还需要考虑并发访问、性能优化、服务治理等方面的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值