2010-02-07 13 views
0

안녕하세요, 에코 클라이언트를 쓰고있어 어떤 이유로 소켓 기능이 오류를 반환하고 INVALID_SOCKET을 (를) 반환하고 있습니다. 왜 그런지 모르겠습니다. 누군가가 내게 이유를 말해 줄 수 있습니까소켓에 연결할 수 없습니다.

/********************************* 
* echo1.cpp     * 
*        * 
* Echo client - version 1  * 
**********************************/ 
#include <winsock2.h> 
#pragma comment(lib, "ws2_32.lib") 
#include <string> 
#include <iostream> 
using namespace std; 

const int MAXBUF = 128; 
const int MAXNAME = 80; 

SOCKET connectsock (char*, char*, char*); 

int main (int argc, char **argv) 
{ 
    char msg[MAXBUF] = ""; 
    char buf[MAXBUF] = ""; 
    char host[MAXNAME] = ""; 
    char service[MAXNAME] = ""; 
    int len; 
    SOCKET s; 

    /* Must always initialize the Windows Sockets TCP/IP library */ 
    WORD wVersion = 0x0202; 
    WSADATA wsaData; 
    int iResult = WSAStartup(wVersion, &wsaData); 
    if (iResult != 0) 
    { 
     cout << "Unable to initialize Windows Socket library." << endl; 
     return 0; 
    } 


    string hostaddress = argv[1]; 

    if(argv[2] == NULL) 
    { 
     strcpy_s(service, MAXNAME, "7"); 
    } 
    else 
    { 
     strcpy_s(service, MAXNAME, argv[2]); 
    } 

    strcpy_s(host, MAXNAME, hostaddress.c_str()); 



    s = connectsock(host, service, "tcp"); 
    if (s != INVALID_SOCKET) 
    { 

     cout <<"Message?"; 
     cin.getline(msg, MAXBUF); 


     // Now, let's try to send the message to the remote machine 


     len = send(s, msg, (int) strlen(msg), 0); 
     if (len > 0) 
     { 
      cout << "Number of bytes sent: " << len << endl; 
      cout << endl; 
     } 
     else 
     { 
      cout << "Unable to send message to remote machine." << endl; 
      return 0; 
     } 

     // Message was sent. Is there a reply from the remote machine? 
     len = recv(s, buf, sizeof(buf), 0); 
     if (len > 0) 
     { 
      cout << "Received message: "; 
      for (int i=0; i<len; i++) cout << buf[i]; 
      cout << endl; 
      cout << "Number of bytes received: " << len << endl << endl; 
     } 
     cout << endl << endl; 

     /* Close the socket (and thus the connection) */ 
     shutdown(s,1); 
     closesocket(s); 
    } 
    WSACleanup(); 
} 


/*------------------------------------------------------------------ 
* connectsock - allocate & connect a remote socket using TCP or UDP 
*------------------------------------------------------------------ 
*/ 
SOCKET connectsock (char *host, char *service, char *protocol) 
{ 
    struct hostent *phe; 
    struct servent *pse; 
    short port; 
    int  ihost; 


    port = htons((u_short) atoi(service)); // 1st try to convert string to integer 
    if (port == 0) 
    {      // if that doesn't work, call service function 
     pse = getservbyname(service,NULL); 
     if (pse) 
     { 
      port = pse->s_port; 
     } 
     else 
     { 
      cout << "Invalid service request." << endl; 
      return INVALID_SOCKET; 
     } 
    } 
/* 
    cout << "Service: " << service << endl; 
    cout << "Port: " << htons(port) << endl; 
*/ 


    ihost = inet_addr(host);  
    if (ihost == INADDR_NONE) 
    { 
     phe = gethostbyname(host); 
     if (phe) 
     { 
      memmove(&ihost, phe->h_addr, phe->h_length); 
     } 
     else 
     { 
      cout << "Invalid Host." << endl; 
      return INVALID_SOCKET; 
     } 
    } 
/* 
    cout << "Network address for hostname:   " << host << endl; 
    cout << "32-bit address in Network Byte Order: " << ihost << endl; 
    cout << "32-bit address in Host Byte Order: " << ntohl(ihost) << endl; 

    struct in_addr in; 
    in.S_un.S_addr = ihost; 
    cout << "Address as dotted decimal:   " << inet_ntoa(in) << endl; 

*/ 

    struct sockaddr_in remote; 
    SOCKET s;     

    if (_stricmp(protocol, "tcp") == 0) 
    { 
     s = socket(AF_INET, SOCK_STREAM, 0); 

     if (s < 0 || s == INVALID_SOCKET) 
     { 
      cout << "Cannot create socket" << endl; 
      return INVALID_SOCKET; 
     } 


     memset(&remote, 0, sizeof(remote)); 
     remote.sin_family = AF_INET; 
     remote.sin_port = htons((u_short) atoi(service)); 
     remote.sin_addr.s_addr = inet_addr(host); 


     int status = connect(s, (LPSOCKADDR) &remote, sizeof(SOCKADDR)); 

     if (status == SOCKET_ERROR) 
     { 
      cout << "Remote host/service not found - or connection refused" << endl; 
      return INVALID_SOCKET; 
     } 
    } 

    else if (_stricmp(protocol,"udp") == 0) 
    { 
     s = socket(AF_INET, SOCK_DGRAM, 0); 
     if (s < 0 || s == INVALID_SOCKET) 
     { 
      cout << "Cannot create socket" << endl; 
      return INVALID_SOCKET; 
     } 
    } 
    else 
    {         // Unknown or unsupported protocol request 
     cout << "Invalid Protocol" << endl; 
     return INVALID_SOCKET; 
    } 

    return s; 
} 
+0

분명히'connectionsock()'함수는 많은 이유로'INVALID_SOCKET'을 반환 할 수 있습니다. 전화를 걸면 기능이 무엇을 인쇄합니까? –

+0

정확히 무엇이 실패하고 있습니까? 연결인가 gethostbyname인가? –

+0

예 - 어떤 법령이 발포하고 있습니까? 그런 다음 GetLastError()를 추가하여 win32 오류 코드 – pm100

답변

3

난 당신 대신 당신이 무엇을 사용의

 remote.sin_port = port; 

를 사용해야한다고 생각 :

 remote.sin_port = htons((u_short) atoi(service)); 

전 기능의 어느 시점에서 이미 포트 번호로 서비스를 전환하려고하기 때문에

. 귀하의 예처럼 서비스가 이름으로 지정된 경우이 코드는 항상 0의 remote.sin_port를 제공합니다.

+0

잘자요. 즉, 포트가 이미 네트워크 순서에 있기 때문에 실제로'remote.sin_port = port;'를 수행해야합니다. –

+0

R 사무엘 : 당신 말이 맞아요. 내 응답을 편집합니다. –

0

이 코드를 실행할 때 이미 사용중인 소켓을 제공하고 있습니까? 할 수있는 창

netstat -a 

소켓이 아직 사용 중이 아닌지 확인하십시오.

참고 : 지금은 명령이 작동 할 수 있도록 창 사용자가 아닙니다.

+2

sysinternals tcpview는 netstat에 해당하는 훌륭한 gui입니다. – pm100

0

@ Diego의 예리한 눈에 기반하여 두 번째 문제점을 발견했습니다. 이 코드 :

remote.sin_addr.s_addr = inet_addr(host); 

이상한 때문에 일찍 체크했다 inet_addr은하고 inet_addr은이 실패한 경우 다시 gethostbyname까지도에 떨어진. 따라서 호스트 네임을 제공했다면 문제가 발생할 것입니다. 다음과 같이 변경해야합니다 :

remote.sin_addr.s_addr = ihost; 
+0

시도해 보니 작동하지 않았다 – Zerobu

+0

ihost로 전환 해 보았지만 여전히 동일한 결과가 나타납니다. – Zerobu

관련 문제