【发布时间】:2014-08-07 08:47:15
【问题描述】:
我有一个作为客户端和服务器的应用程序。作为服务器,它在端口 xxxx[代理 URL] 上接受 SOAP 请求,并在端口 yyyy [通知 URL] 上向发送者发送通知。
所以基本上它在端口 xxxx 上充当服务器,在端口 yyyy 上充当客户端。我的服务有一个 IPv6 或 IPv4 的专用 IP。
我们使用 GSOAP 进行通信并覆盖 GSOAP 函数 tcp_connect() 进行客户端绑定。
目前,我面临着将服务过渡到 IPv6 的问题。用例:当我监听 IPv6 地址并且我的通知 URL 是 IPv4...
从 GSOAP 实现中,从通知 URL 创建一个套接字。
sk = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
现在我们尝试相应地绑定到这个套接字(IPv4 或 IPv6):
struct addrinfo hints, *res, *p;
int status;
const char* client_ip = AGENT_CLIENT_IP;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if( (status=getaddrinfo(client_ip, NULL, &hints, &res))!=0 )
{
sprintf(err_msg_buf,"bind failed in tcp_connect()");
soap->fclosesocket(soap, sk);
return error;
}
for( p=res; p!=NULL; p=p->ai_next){
if(p->ai_family == AF_INET)
{
struct sockaddr_in * ipv4 = (struct sockaddr_in *)p->ai_addr;
status = bind(sk, ipv4, (int)sizeof(struct sockaddr_in));
}
else if(p->ai_family == AF_INET6)
{
struct sockaddr_in6 * ipv6 = (struct sockaddr_in6 *)p->ai_addr;
status = bind(sk, ipv6, (int)sizeof(struct sockaddr_in6));
}
else
{
sprintf(err_msg_buf,"tcp_connect() error. IP Address neither IPv6 nor IPv4 ");
soap->fclosesocket(soap, sk);
return error;
}
break;
}
if(-1 == status)
{
sprintf(err_msg_buf," Binding to client host ip failed in tcp_connect()");
return error;
}
由于已经创建了套接字(根据 Notification URL 的类型),如果套接字类型不匹配,则绑定失败。
当套接字系列和代理IP地址属于不同系列时,如何使我的客户端绑定工作?
【问题讨论】:
-
我知道这不是一个解决方案,但我的第一个想法是“将应用程序拆分为单独的客户端和服务器部分,每个部分都可以独立为 IPv4 或 IPv6,并使用某种 IPC 来链接它们"
-
看来您必须创建两个单独的套接字。这不可能吗?