全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:139
推到 Plurk!
推到 Facebook!

請教Socket通訊

尚未結案
blue
中階會員


發表:116
回覆:106
積分:59
註冊:2002-04-15

發送簡訊給我
#1 引用回覆 回覆 發表時間:2018-01-15 17:37:29 IP:125.227.xxx.xxx 未訂閱
Hi,各位先進大家好:
很抱歉,問一個 VC 的問題,
目前將舊的 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;

}


不知該從何查資料?
謝謝!
系統時間:2018-02-24 0:32:02
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!