标签归档:socket

Tomcat请求HTTPS的注意事项

需要在catalia.sh里给JAVA_OPTS再增加一个参数

-Dsun.security.ssl.allowUnsafeRenegotiation=true

在解决这个问题上,我走了不少弯路
在开发过程中(Windows)项目使用了cxf来进行webservice的请求封装,一切正常
部署到服务器(Linux)后总是报SocketTimeOutException
在排除了编码问题、IP限制和证书错误(命令行使用curl请求获取到了正确的响应)的可能之后,基本定位在cxf本身的问题

由于cxf代码过于庞杂,部署源码环境很痛苦,最后使用HttpClient拼装满足格式的xml请求模拟SOAP写了一个测试类
使用java命令行执行后得到正确结果,将测试程序放到Tomcat启动,这时候出现了异常的错误信息:

SSLException: HelloRequest followed by an unexpected handshake message

以这个异常为关键词搜索很容易得到本文开头加参数的解决办法,于是加上以后cxf的连接也正常了
那为什么cxf不报正确的异常信息呢?大概是两种可能:
1、cxf的封装太严实了,没有给出正确的日志信息,不过对于这种成型的框架应该不会有这种低级问题
2、大概看了一下cxf的实现,有点类似异步模型,在允许的超时时间内没有取到响应导致抛出的异常为超时

至于Windows下不会出现这个问题,大概是因为不同系统的安全策略吧,不求甚解了
希望对在非Windows系统(MacOS下也是一样的症状)下碰到此问题的人有帮助

PS. 此问题应该不仅限于Tomcat,其他web容器估计也是一样的

[Socket]获取客户端IP

有两种方法,一种是在accept的时候获取,一种是通过getpeername获取


#include

int accept(int socket, struct sockaddr *restrict address,
socklen_t *restrict address_len);

int getpeername(int socket, struct sockaddr *restrict address,
socklen_t *restrict address_len);

两者区别主要在取IP的fd不一样,前者是在监听的fd,后者是在连接建立的fd

struct sockaddr_in addr;
socklen_t addr_len;
int32_t listen_fd, sock_fd;

/* create listening port */

addr_len = sizeof(addr);

memset(&addr, 0, addr_len);
sock_fd = accept(listen_fd, (struct sockaddr *)&addr, &addr_len);
printf(“%d\n”, addr.sin_addr.s_addr);

memset(&addr, 0, addr_len);
getpeername(sock_fd, (struct sockaddr *)&addr, &addr_len);
printf(“%d\n”, addr.sin_addr.s_addr);

当然这种长整型格式的IP不一定是我们想要的,可以通过inet_ntoa转换


#include

in_addr_t inet_addr(const char *cp);
char *inet_ntoa(struct in_addr in);


printf(“%s\n”, inet_ntoa(addr));