2010-05-18 3 views
2

다음 두 가지 코드는 컴파일되지만 클라이언트 쪽에서는 connect() failed 오류가 발생합니다. (MinGW로 컴파일).c windows connect()가 실패합니다. 오류 10049

클라이언트 코드 :

// thanks to cs.baylor.edu/~donahoo/practical/CSockets/code/TCPEchoClientWS.c 

#include <stdio.h> 
#include <winsock.h> 
#include <stdlib.h> 

#define RCVBUFSIZE 32 // size of receive buffer 

void DieWithError(char *errorMessage); 

int main(int argc, char* argv[]) 
{ 
    int sock; 
    struct sockaddr_in echoServAddr; 
    unsigned short echoServPort; 
    char *servIP; 
    char *echoString; 
    char echoBuffer[RCVBUFSIZE]; 
    int echoStringLen; 
    int bytesRcvd, totalBytesRcvd; 
    WSAData wsaData; 

    if((argc < 3) || (argc > 4)){ 
    fprintf(stderr, "Usage: %s <Sever IP> <Echo Word> [<Echo Port>]\n", argv[0]); 
    exit(1); 
    } 

    if (argc==4) 
    echoServPort = atoi(argv[3]); // use given port if any 
    else 
    echoServPort = 7; // echo is well-known port for echo service 

    if(WSAStartup(MAKEWORD(2, 0), &wsaData) != 0){ // load winsock 2.0 dll 
    fprintf(stderr, "WSAStartup() failed"); 
    exit(1); 
    } 

    // create reliable, stream socket using tcp 
    if((sock=socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) 
    DieWithError("socket() failed"); 

    // construct the server address structure 
    memset(&echoServAddr, 0, sizeof(echoServAddr)); 
    echoServAddr.sin_family = AF_INET; 
    echoServAddr.sin_addr.s_addr = inet_addr(servIP); // server IP address 
    echoServAddr.sin_port = htons(echoServPort); 
    // establish connection to the echo server 
    if(connect(sock, (struct sockaddr*)&echoServAddr, sizeof(echoServAddr)) < 0) 
    DieWithError("connect() failed"); 

    echoStringLen = strlen(echoString); // determine input length 

    // send the string, includeing the null terminator to the server 
    if(send(sock, echoString, echoStringLen, 0)!= echoStringLen) 
    DieWithError("send() sent a different number of bytes than expected"); 

    totalBytesRcvd = 0; 
    printf("Received: "); // setup to print the echoed string 
    while(totalBytesRcvd < echoStringLen){ 
    // receive up to the buffer size (minus 1 to leave space for a null terminator) bytes from the sender 
    if(bytesRcvd = recv(sock, echoBuffer, RCVBUFSIZE-1, 0) <= 0) 
     DieWithError("recv() failed or connection closed prematurely"); 
    totalBytesRcvd += bytesRcvd; // keep tally of total bytes 
    echoBuffer[bytesRcvd] = '\0'; 
    printf("%s", echoBuffer); // print the echo buffer 
    } 

    printf("\n"); 
    closesocket(sock); 
    WSACleanup(); 

    exit(0); 
} 

void DieWithError(char *errorMessage) 
{ 
    fprintf(stderr, "%s: %d\n", errorMessage, WSAGetLastError()); 
    exit(1); 
} 

서버 코드 :

// thanks cs.baylor.edu/~donahoo/practical/CSockets/code/TCPEchoServerWS.c 

#include <stdio.h> 
#include <winsock.h> 
#include <stdlib.h> 

#define MAXPENDING 5 // maximum outstanding connection requests 
#define RCVBUFSIZE 1000 

void DieWithError(char *errorMessage); 
void HandleTCPClient(int clntSocket); // tcp client handling function 

int main(int argc, char **argv) 
{ 
    int serverSock; 
    int clientSock; 
    struct sockaddr_in echoServerAddr; 
    struct sockaddr_in echoClientAddr; 
    unsigned short echoServerPort; 
    int clientLen; // length of client address data structure 
    WSAData wsaData; 

    if (argc!=2){ 
    fprintf(stderr, "Usage: %s <Server Port>\n", argv[0]); 
    exit(1); 
    } 

    echoServerPort = atoi(argv[1]); 

    if(WSAStartup(MAKEWORD(2, 0), &wsaData)!=0){ 
    fprintf(stderr, "WSAStartup() failed"); 
    exit(1); 
    } 

    // create socket for incoming connections 
    if((serverSock=socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))<0) 
    DieWithError("socket() failed"); 

    // construct local address structure 
    memset(&echoServerAddr, 0, sizeof(echoServerAddr)); 
    echoServerAddr.sin_family = AF_INET; 
    echoServerAddr.sin_addr.s_addr = htonl(INADDR_ANY); // any incoming interface 
    echoServerAddr.sin_port = htons(echoServerPort); // local port 

    // bind to the local address 
    if(bind(serverSock, 
     (struct sockaddr*)&echoServerAddr, 
     sizeof(echoServerAddr) 
    )<0) 
    DieWithError("bind() failed"); 

    // mark the socket so it will listen for incoming connections 
    if(listen(serverSock, MAXPENDING)<0) 
    DieWithError("listen() failed"); 

    for (;;){ // run forever 
    // set the size of the in-out parameter 
    clientLen = sizeof(echoClientAddr); 

    // wait for a client to connect 
    if((clientSock = accept(serverSock, (struct sockaddr*)&echoClientAddr, 
       &clientLen)) < 0) 
     DieWithError("accept() failed"); 

    // clientSock is connected to a client 

    printf("Handling client %s\n", inet_ntoa(echoClientAddr.sin_addr)); 

    HandleTCPClient(clientSock); 
    } 

    // NOT REACHED 
} 

void DieWithError(char *errorMessage) 
{ 
    fprintf(stderr, "%s: %d\n", errorMessage, WSAGetLastError()); 
    exit(1); 
} 

void HandleTCPClient(int clientSocket) 
{ 
    char echoBuffer[RCVBUFSIZE]; // buffer for echostring 
    int recvMsgSize; // size of received message 

    // receive message from client 
    if((recvMsgSize = recv(clientSocket, echoBuffer, RCVBUFSIZE, 0) <0)) 
    DieWithError("recv() failed"); 

    // send received string and receive again until end of transmission 
    while(recvMsgSize > 0){ 
    // echo message back to client 
    if(send(clientSocket, echoBuffer, recvMsgSize, 0)!=recvMsgSize) 
     DieWithError("send() failed"); 

    // see if there's more data to receive 
    if((recvMsgSize = recv(clientSocket, echoBuffer, RCVBUFSIZE, 0)) <0) 
     DieWithError("recv() failed"); 
    } 

    closesocket(clientSocket); // close client socket 
} 

가 어떻게이 문제를 해결할 수 있습니까?

+0

@ Joshua Moore이게 숙제입니까? 코드는 잘된 것처럼 보이지만 로컬 호스트에 방화벽 규칙이 있습니까? 몇 주 전에 저는이 일을했습니다 (간단한 클라이언트/서버),하지만 그것은 리눅스였습니다 ... 저는 방황했습니다, 내 코드가 MinGW로 컴파일됩니까?! :) – mosg

+0

@mosg 나는 몇 달 전에 숙제로 리눅스 버전을 만들었습니다. 며칠 전 나는 창문 용으로 수정 된 리눅스 코드 인이 파일들을 발견했습니다. http://cs.baylor.edu/~donahoo/practical/CSockets/winsock.html – lowerkey

+0

@ Joshua Moore Ok :) 좋은 숙제! 단순한 코드 카가 옳았다. – mosg

답변

1

당신은 servIP를 초기화하지 않습니다

servIP = argv[1]; 

난 당신이 디버거를 몇 초에 이러한 종류의 실수를 발견 할 수있었습니다해야하기 때문에 당신이 정말로, 디버거에 익숙해 질 필요가 있다고 생각.

+0

디버거를 사용하고 있지 않습니다. 솔직하게, 나는 그것을 어떻게 사용하는지 정말로 모른다. 학교에서 우리는 GDB에 대해 간략하게 소개되었습니다. 저것은 배우기 좋은가? – lowerkey

+0

줄을 추가했습니다. servIP = argv [1]; 및 첫 번째 if-block 바로 뒤의 echoString = argv [2]. Connect()가 작동하지만 recv() 오류가 발생합니다 : recv()가 실패했거나 연결이 너무 일찍 종료되었습니다 : 0 – lowerkey

0

문제는 클라이언트 쪽입니다.

  1. servIP에는 적절한 값이 할당되어 있지 않습니다. 해야 할 일

    servIP = argv [1];

로드 전 winsock2 dll.

2 이는 recv (...)가 0을 반환하는 정상적인 경우입니다. 연결이 닫혀 있음을 의미합니다.

+0

recv 줄은 으로 읽어야합니다. if (recv (...) <0) DieWithError() 대신에 if (recv (...) <= 0) DieWithError()'? 또한 프로그램은 수신 된 문자열을 인쇄합니다. 대신 오류 메시지가 출력됩니다. – lowerkey

+0

예 (recv (...) <0) 인 경우 DieWithError(). 회선에 트래픽이 없을 때 0이 유효합니다! – KedarX

관련 문제