2015-04-22 53 views
0

我有一個簡單的win32應用程序,我用它來發布到usenet。我也用它來發送電子郵件。使用Winsockets連接到一個URL

對的Usenet張貼代碼片段是這樣的:

... 
WSAAsyncSelect(conn_sock,mywin,nRet,FD_CONNECT|FD_READ|FD_WRITE|FD_CLOSE|FD_ACCEPT); 
lpServEnt = getservbyname("nntp", "tcp"); 
saServ.sin_family = AF_INET; 
saServ.sin_addr = *((LPIN_ADDR)*lpHostEnt->h_addr_list); 
nRet = connect((SOCKET)conn_sock,(LPSOCKADDR)&saServ,sizeof(SOCKADDR_IN)); 
... etc. 

它運作良好。當我將「nntp」更改爲「smtp」時,我可以發送電子郵件。如果它是「http」,我的代碼不能正常工作。如果地址是「localhost」,「127,0,01」或「192.168.0.5」,我可以連接和GET/POST,但如果我使用「195.nn.nn.nn」或「www.somesite.com」等等。

我錯過了什麼?我試圖避免使用HttpOpenRequest()等功能,並使用send()recv()等。

回答

1

connect()需要數字格式的IP地址。

getservbyname()旨在檢索服務數據庫中註冊的服務提供商的IP地址和端口,以便查找。例如,如果客戶端位於擁有自己的SMTP服務器的企業網絡中,則可以註冊SMTP服務提供商,這樣可以使用getservbyname("smtp")getaddrinfo("smtp")。不過,註冊HTTP服務提供商的可能性較小。而且大多數最終用戶甚至沒有在他們的PC上安裝服務提供商數據庫,或者它是空的。

如果您有主機名(「smtp.somesite.com」,「nntp.somesite.com」,「www.somesite.com」等),則需要使用gethostbyname()getaddrinfo()將主機名解析爲IP地址:

hostent *lpHostEnt = gethostbyname("nntp.somesite.com"); 
if ((lpHostEnt) && (lpHostEnt->h_addrtype == AF_INET)) 
{ 
    saServ.sin_family = AF_INET; 
    saServ.sin_addr = *((LPIN_ADDR)(lpHostEnt->h_addr)); 
    saServ.sin_port = htons(119); 
    nRet = connect(conn_sock, (LPSOCKADDR)&saServ, sizeof(saServ)); 
} 

addr_info hints = {0}; 
hints.ai_family = AF_INET; 
hints.ai_socktype = SOCK_STREAM; 
hints.ai_protocol = IPPROTO_TCP; 

addr_info *addr = NULL; 

nRet = getaddrinfo("nntp.somesite.com", "119", &hints, &addr); 
if (nRet == 0) 
{ 
    nRet = connect(conn_sock, addr->ai_addr, addr->ai_addrlen); 
    freeaddrinfo(addr); 
} 

如果您有字符串格式的IP地址,而不是( 「127.0.0.1」, 「192.168.0.5」,等等),你需要使用inet_addr()getaddrinfo()將字符串轉換爲數字格式:

saServ.sin_family = AF_INET; 
saServ.sin_addr = inet_addr("192.168.0.5"); 
saServ.sin_port = htons(119); 
nRet = connect(conn_sock, (LPSOCKADDR)&saServ, sizeof(saServ)); 

addr_info hints = {0}; 
hints.ai_flags = AI_NUMERICHOST; 
hints.ai_family = AF_INET; 
hints.ai_socktype = SOCK_STREAM; 
hints.ai_protocol = IPPROTO_TCP; 

addr_info *addr = NULL; 

nRet = getaddrinfo("192.168.0.5", "119", &hints, &addr); 
if (nRet == 0) 
{ 
    nRet = connect(conn_sock, addr->ai_addr, addr->ai_addrlen); 
    freeaddrinfo(addr); 
} 

這些是你的代碼需要支持最常見的情況。 getservbyname()不常用。