台灣最大程式設計社群網站
線上人數
1279
 
會員總數:242636
討論主題:187614
歡迎您免費加入會員
討論區列表 >> C/C++ >> 請教Socket通訊
[]  
[我要回覆]
回應主題 加入我的關注話題 檢舉此篇討論 將提問者加入個人黑名單
請教Socket通訊
價值 : 50 QP  點閱數:261 回應數:0

樓主

Blue
初學者
317 84
980 166
發送站內信

Hi,各位先進大家好:
目前將舊的 IPv4 socket 程式開寫為 IPv4 & IPv6 相容,
其中有一段使用剛建立Listen 的Socket來主動向對方發起通訊,
如下程序是可以正常使用同一 SockFD Listen 並對 192.168.1.100 UDP 8008 進行傳送封包

SockFD = IPv4_Listen(port, false);
if (SockFD == -1) {
cout << "call tcp_listen error" << endl;
return -1;
}
IPv4_Connect(SockFD, PCHAR("192.168.1.100"), 8008);

SOCKET IPv4_Listen(int port, bool istcp) {
SOCKET s = -1;
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_family = AF_INET;
sin.sin_port = port;

if ((s = socket(AF_INET, istcp ? SOCK_STREAM : SOCK_DGRAM, istcp ? 0 : IPPROTO_UDP)) == -1) return s;
if (bind(s, (struct sockaddr *)&sin, sizeof(struct sockaddr_in)) < 0) {
closesocket(s);
s = -1;
return s;
}

if (istcp) {
if (listen(s, 5)) {
closesocket(s);
s = -1;
return s;
}
}
return s;
}

void IPv4_Connect(SOCKET SockFD, char * Address, int port) {
struct sockaddr_in sin;

memset(&sin, 0, sizeof(sin));
sin.sin_addr.s_addr = inet_addr(Address);
sin.sin_family = AF_INET;
sin.sin_port = htons(port);

// if (-1 == connect(SockFD, (struct sockaddr *)&sin, sizeof(struct sockaddr_in))) {
// cout << "connect error: " << strerror(errno) << endl;
// return;
// }
char *buf = "aaaaaaaaaaaaaaa";
int x = sendto(SockFD,buf, 10, 0, (struct sockaddr *)&sin, sizeof(struct sockaddr_in));
printf("Send bytes = %d\r\n", x);

}

但,改寫為 IPv6 相容時,只要有 Bind, 該 SockFD 即無法對 192.168.1.100 UDP 8008 送出封包

SockFD = IPv6_Listen(port, false);
if (SockFD == -1) {
cout << "call tcp_listen error" << endl;
return -1;
}
IPv6_Connect(SockFD, PCHAR("192.168.1.100"), 8008, false);

SOCKET IPv6_CreateAndListen(struct addrinfo *res, bool istcp) {
SOCKET s = -1;

if (-1 == (s = socket(res->ai_family, res->ai_socktype, res->ai_protocol))) return -1;

if (bind(s, res->ai_addr, res->ai_addrlen) == SOCKET_ERROR) {
closesocket(s);
return -1;
}
if (istcp) {
if (listen(s, 5)) {
closesocket(s);
s = -1;
return -1;
}
}
return s;
}

SOCKET IPv6_Listen(int port, bool istcp) {
SOCKET s = -1;
struct addrinfo hints, *res, *ressave;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_PASSIVE;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = istcp ? SOCK_STREAM : SOCK_DGRAM;
hints.ai_protocol = istcp ? IPPROTO_IP : IPPROTO_UDP;

char service[100];
itoa(port, service, 10);

if (0 != getaddrinfo(PCHAR("127.0.0.1"), service, &hints, &res)) return -1;

ressave = res;
while(NULL != res) {
s = IPv6_CreateAndListen(* &res, istcp);
if (s == -1) {
res = res->ai_next;
continue;
}
break;
}
freeaddrinfo(ressave);
return s;

}

int IPv6_Connect(SOCKET SockFD, char *Address, int port, bool istcp) {
struct addrinfo hints, *res, *ressave;
ZeroMemory(&hints, sizeof(hints));
hints.ai_flags = AI_PASSIVE;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = istcp ? SOCK_STREAM : SOCK_DGRAM;
hints.ai_protocol = istcp ? IPPROTO_IP : IPPROTO_UDP;

char service[100];
itoa(port, service, 10);

if (0 != getaddrinfo(Address, service, &hints, &res)) return -1;

ressave = res;
while (NULL != res)
{
if (istcp) {
if (-1 == connect(SockFD, res->ai_addr, res->ai_addrlen))
{
cout << "connect error: " << strerror(errno) << endl;
closesocket(SockFD);
res = res->ai_next;
continue;
}
}
char *buf = "aaaaaaaaaaaaaaa";
int x = sendto(SockFD,buf, 10, 0, res->ai_addr, res->ai_addrlen);
printf("Send bytes = %d\r\n", x);

break;
}

freeaddrinfo(ressave);

if (NULL == res) return -1;

}


不知該從何查資料?
謝謝!





搜尋相關Tags的文章: [ IPv4 & IPv6 ] ,
本篇文章發表於2018-01-15 17:37
別忘捐VP感謝幫助你的人 新手會員瞧一瞧
目前尚無任何回覆
   

回覆
如要回應,請先登入.