HTTP POST를 수행하고 응답을 사용하는 간단한 C 예제


90

HTTP 게시를 수행하는 매우 간단한 C 애플리케이션을 만들고 싶습니다. 몇 가지 매개 변수가 필요하며이를 사용하여 URL을 구성합니다. 간단한 HTTP POST를 수행하고 curl을 사용하지 않고 응답을 받고 싶습니다.

의사 코드 :

  1. 2 개의 인수 처리

  2. 템플릿 URL에 인수 입력 : http://api.somesite.com/apikey=ARG1&command=ARG2

  3. 생성 된 URL에서 POST 수행

  4. 응답 소비

내 Google 및 SO 검색은이 문제에 대해 아무것도 산출하지 못했습니다.


2
어떤 종류의 네트워크 프레임 워크를 사용하십니까? 어떤 OS를 사용하십니까?
cnicutar

기본 Fedora 또는 Cent 상자 일뿐입니다. 네트워크 프레임 워크는 일반적인 sys / socket, netdb, arpa / inet입니다. libcurl이 아닙니다.
kmarks2 2014

1
libcurl이 아닙니다. 다른 도서관과 함께 갈 의향이 있습니까, 아니면 모두 POSIX 여야합니까?
cnicutar

불행히도 모든 POSIX. 모든 시스템에서 완전히 독립되어 있어야합니다.
kmarks2 2014

2
내가 만든 샘플이 있지만 메시지 본문이없는 경우 POST를 사용하는 이유를 이해할 수 없습니다. 모든 매개 변수가 쿼리 문자열에있는 경우 GET을 수행하지 않는 이유는 무엇입니까?
Jerry Jeremiah

답변:


191

메시지에는 빈 줄로 구분 된 헤더 부분과 메시지 본문이 있습니다. 메시지 본문이 없더라도 빈 줄은 항상 필요합니다. 헤더는 명령으로 시작하며 콜론과 공백으로 구분 된 추가 키 값 쌍 행이 있습니다. 메시지 본문이있는 경우 원하는 모든 것이 될 수 있습니다.

헤더의 줄과 헤더 끝에있는 빈 줄은 carraige 리턴 및 줄 바꿈 쌍 ( HTTP 헤더 줄 바꿈 스타일 참조)으로 끝나야 하므로 해당 줄의 끝에 \ r \ n이 있습니다.

URL의 형식은 다음과 같습니다. http://host:port/path?query_string

웹 사이트에 요청을 제출하는 두 가지 주요 방법이 있습니다.

  • GET : 쿼리 문자열은 선택 사항이지만 지정된 경우 합리적으로 짧아야합니다. 이 때문에 헤더는 GET 명령이 될 수 있으며 다른 것은 없습니다. 샘플 메시지는 다음과 같습니다.

    GET /path?query_string HTTP/1.0\r\n
    \r\n
    
  • POST : 일반적으로 쿼리 문자열에있는 것은 대신 메시지 본문에 있습니다. 이 때문에 헤더에 Content-Type : 및 Content-Length : 속성과 POST 명령이 포함되어야합니다. 샘플 메시지는 다음과 같습니다.

    POST /path HTTP/1.0\r\n
    Content-Type: text/plain\r\n
    Content-Length: 12\r\n
    \r\n
    query_string
    

따라서 귀하의 질문에 답하기 위해 : POST에 관심이있는 URL이 http://api.somesite.com/apikey=ARG1&command=ARG2 이면 본문이나 쿼리 문자열이 없기 때문에 POST 할 이유가 없습니다. 메시지 본문에 넣을 것이 없으므로 Content-Type : 및 Content-Length에 넣을 것이 없습니다.

정말로 원한다면 게시 할 수있을 것 같습니다. 이 경우 메시지는 다음과 같습니다.

POST /apikey=ARG1&command=ARG2 HTTP/1.0\r\n
\r\n

따라서 메시지를 보내려면 C 프로그램이 다음을 수행해야합니다.

  • 소켓 생성
  • IP 주소 조회
  • 소켓을 열다
  • 요청을 보내다
  • 응답을 기다리다
  • 소켓을 닫으십시오

전송 및 수신 호출은 사용자가 제공 한 모든 데이터를 반드시 전송 / 수신하는 것은 아닙니다. 실제로 전송 / 수신 된 바이트 수를 반환합니다. 루프에서 호출하고 나머지 메시지를 보내고받는 것은 사용자에게 달려 있습니다.

이 샘플에서 내가하지 않은 것은 일종의 실제 오류 검사입니다. 무언가가 실패하면 프로그램을 종료합니다. 그것이 당신을 위해 작동하는지 알려주십시오.

#include <stdio.h> /* printf, sprintf */
#include <stdlib.h> /* exit */
#include <unistd.h> /* read, write, close */
#include <string.h> /* memcpy, memset */
#include <sys/socket.h> /* socket, connect */
#include <netinet/in.h> /* struct sockaddr_in, struct sockaddr */
#include <netdb.h> /* struct hostent, gethostbyname */

void error(const char *msg) { perror(msg); exit(0); }

int main(int argc,char *argv[])
{
    /* first what are we going to send and where are we going to send it? */
    int portno =        80;
    char *host =        "api.somesite.com";
    char *message_fmt = "POST /apikey=%s&command=%s HTTP/1.0\r\n\r\n";

    struct hostent *server;
    struct sockaddr_in serv_addr;
    int sockfd, bytes, sent, received, total;
    char message[1024],response[4096];

    if (argc < 3) { puts("Parameters: <apikey> <command>"); exit(0); }

    /* fill in the parameters */
    sprintf(message,message_fmt,argv[1],argv[2]);
    printf("Request:\n%s\n",message);

    /* create the socket */
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) error("ERROR opening socket");

    /* lookup the ip address */
    server = gethostbyname(host);
    if (server == NULL) error("ERROR, no such host");

    /* fill in the structure */
    memset(&serv_addr,0,sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(portno);
    memcpy(&serv_addr.sin_addr.s_addr,server->h_addr,server->h_length);

    /* connect the socket */
    if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
        error("ERROR connecting");

    /* send the request */
    total = strlen(message);
    sent = 0;
    do {
        bytes = write(sockfd,message+sent,total-sent);
        if (bytes < 0)
            error("ERROR writing message to socket");
        if (bytes == 0)
            break;
        sent+=bytes;
    } while (sent < total);

    /* receive the response */
    memset(response,0,sizeof(response));
    total = sizeof(response)-1;
    received = 0;
    do {
        bytes = read(sockfd,response+received,total-received);
        if (bytes < 0)
            error("ERROR reading response from socket");
        if (bytes == 0)
            break;
        received+=bytes;
    } while (received < total);

    if (received == total)
        error("ERROR storing complete response from socket");

    /* close the socket */
    close(sockfd);

    /* process response */
    printf("Response:\n%s\n",response);

    return 0;
}

지적한 다른 답변과 마찬가지로 4096 바이트는 그다지 큰 응답이 아닙니다. 귀하의 요청에 대한 응답이 짧을 것이라고 가정하여 무작위로 해당 번호를 선택했습니다. 크기가 클 수있는 경우 두 가지 선택이 있습니다.

  • 응답에서 Content-Length : 헤더를 읽은 다음 전체 응답을 저장할 충분한 메모리를 동적으로 할당합니다.
  • 조각이 도착하면 파일에 응답을 작성합니다.

댓글에 묻는 질문에 대한 추가 정보 :

메시지 본문에 데이터를 POST하려면 어떻게해야합니까? 그런 다음 Content-Type : 및 Content-Length : 헤더를 포함해야합니다. Content-Length : 헤더와 본문을 구분하는 빈 줄 뒤의 모든 항목의 실제 길이입니다.

다음은 다음 명령 줄 인수를 사용하는 샘플입니다.

  • 주최자
  • 포트
  • 명령 (GET 또는 POST)
  • 경로 (쿼리 데이터 제외)
  • 쿼리 데이터 (GET의 경우 쿼리 문자열에, POST의 경우 본문에 입력)
  • 헤더 목록 (Content-Length : POST를 사용하는 경우 자동)

따라서 원래 질문에 대해 다음을 실행합니다.

a.out api.somesite.com 80 GET "/apikey=ARG1&command=ARG2"

그리고 코멘트에서 묻는 질문에 대해 실행합니다.

a.out api.somesite.com 80 POST / "name=ARG1&value=ARG2" "Content-Type: application/x-www-form-urlencoded"

다음은 코드입니다.

#include <stdio.h> /* printf, sprintf */
#include <stdlib.h> /* exit, atoi, malloc, free */
#include <unistd.h> /* read, write, close */
#include <string.h> /* memcpy, memset */
#include <sys/socket.h> /* socket, connect */
#include <netinet/in.h> /* struct sockaddr_in, struct sockaddr */
#include <netdb.h> /* struct hostent, gethostbyname */

void error(const char *msg) { perror(msg); exit(0); }

int main(int argc,char *argv[])
{
    int i;

    /* first where are we going to send it? */
    int portno = atoi(argv[2])>0?atoi(argv[2]):80;
    char *host = strlen(argv[1])>0?argv[1]:"localhost";

    struct hostent *server;
    struct sockaddr_in serv_addr;
    int sockfd, bytes, sent, received, total, message_size;
    char *message, response[4096];

    if (argc < 5) { puts("Parameters: <host> <port> <method> <path> [<data> [<headers>]]"); exit(0); }

    /* How big is the message? */
    message_size=0;
    if(!strcmp(argv[3],"GET"))
    {
        message_size+=strlen("%s %s%s%s HTTP/1.0\r\n");        /* method         */
        message_size+=strlen(argv[3]);                         /* path           */
        message_size+=strlen(argv[4]);                         /* headers        */
        if(argc>5)
            message_size+=strlen(argv[5]);                     /* query string   */
        for(i=6;i<argc;i++)                                    /* headers        */
            message_size+=strlen(argv[i])+strlen("\r\n");
        message_size+=strlen("\r\n");                          /* blank line     */
    }
    else
    {
        message_size+=strlen("%s %s HTTP/1.0\r\n");
        message_size+=strlen(argv[3]);                         /* method         */
        message_size+=strlen(argv[4]);                         /* path           */
        for(i=6;i<argc;i++)                                    /* headers        */
            message_size+=strlen(argv[i])+strlen("\r\n");
        if(argc>5)
            message_size+=strlen("Content-Length: %d\r\n")+10; /* content length */
        message_size+=strlen("\r\n");                          /* blank line     */
        if(argc>5)
            message_size+=strlen(argv[5]);                     /* body           */
    }

    /* allocate space for the message */
    message=malloc(message_size);

    /* fill in the parameters */
    if(!strcmp(argv[3],"GET"))
    {
        if(argc>5)
            sprintf(message,"%s %s%s%s HTTP/1.0\r\n",
                strlen(argv[3])>0?argv[3]:"GET",               /* method         */
                strlen(argv[4])>0?argv[4]:"/",                 /* path           */
                strlen(argv[5])>0?"?":"",                      /* ?              */
                strlen(argv[5])>0?argv[5]:"");                 /* query string   */
        else
            sprintf(message,"%s %s HTTP/1.0\r\n",
                strlen(argv[3])>0?argv[3]:"GET",               /* method         */
                strlen(argv[4])>0?argv[4]:"/");                /* path           */
        for(i=6;i<argc;i++)                                    /* headers        */
            {strcat(message,argv[i]);strcat(message,"\r\n");}
        strcat(message,"\r\n");                                /* blank line     */
    }
    else
    {
        sprintf(message,"%s %s HTTP/1.0\r\n",
            strlen(argv[3])>0?argv[3]:"POST",                  /* method         */
            strlen(argv[4])>0?argv[4]:"/");                    /* path           */
        for(i=6;i<argc;i++)                                    /* headers        */
            {strcat(message,argv[i]);strcat(message,"\r\n");}
        if(argc>5)
            sprintf(message+strlen(message),"Content-Length: %d\r\n",strlen(argv[5]));
        strcat(message,"\r\n");                                /* blank line     */
        if(argc>5)
            strcat(message,argv[5]);                           /* body           */
    }

    /* What are we going to send? */
    printf("Request:\n%s\n",message);

    /* create the socket */
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) error("ERROR opening socket");

    /* lookup the ip address */
    server = gethostbyname(host);
    if (server == NULL) error("ERROR, no such host");

    /* fill in the structure */
    memset(&serv_addr,0,sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(portno);
    memcpy(&serv_addr.sin_addr.s_addr,server->h_addr,server->h_length);

    /* connect the socket */
    if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
        error("ERROR connecting");

    /* send the request */
    total = strlen(message);
    sent = 0;
    do {
        bytes = write(sockfd,message+sent,total-sent);
        if (bytes < 0)
            error("ERROR writing message to socket");
        if (bytes == 0)
            break;
        sent+=bytes;
    } while (sent < total);

    /* receive the response */
    memset(response,0,sizeof(response));
    total = sizeof(response)-1;
    received = 0;
    do {
        bytes = read(sockfd,response+received,total-received);
        if (bytes < 0)
            error("ERROR reading response from socket");
        if (bytes == 0)
            break;
        received+=bytes;
    } while (received < total);

    if (received == total)
        error("ERROR storing complete response from socket");

    /* close the socket */
    close(sockfd);

    /* process response */
    printf("Response:\n%s\n",response);

    free(message);
    return 0;
}

호출시 어떤 인수를 전달해야합니까?
Santiago Martí Olbrich 2015 년

첫 번째 매개 변수로 apikey로 사용될 무언가를 전달하고 명령으로 사용될 두 번째 매개 변수의 무언가를 전달해야합니다. 완전히 다른 쿼리 문자열을 사용하려면 형식 문자열, 매개 변수 수 및 사용 메시지를 변경해야합니다.
Jerry Jeremiah

2
이 코드는 잘못된 HTTP 요청을 내 보냅니다. HTTP는 요청 행이 캐리지 리턴 / 라인 피드 쌍 ( \r\n) 으로 종료되어야한다고 지정 하지만이 코드는 베어 라인 피드를 사용합니다.
John Bollinger

@JohnBollinger 그것은 매우 사실입니다. 지적 해 주셔서 감사합니다. 편집 된 답변이 더 낫기를 바랍니다.
Jerry Jeremiah

이 게시물 메시지의 문제점은 무엇입니까? "POST /variableName=%s&value=%s HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 4\r\n\r\n\r\n"name = reaz처럼 게시하고 싶습니다. 그것은 400 잘못된 요청 응답
Reaz Murshed

12

Jerry의 대답은 훌륭합니다. 그러나 큰 응답은 처리하지 않습니다. 이를 처리하기위한 간단한 변경 :

memset(response, 0, sizeof(response));
total = sizeof(response)-1;
received = 0;
do {
    printf("RESPONSE: %s\n", response);
    // HANDLE RESPONSE CHUCK HERE BY, FOR EXAMPLE, SAVING TO A FILE.
    memset(response, 0, sizeof(response));
    bytes = recv(sockfd, response, 1024, 0);
    if (bytes < 0)
        printf("ERROR reading response from socket");
    if (bytes == 0)
        break;
    received+=bytes;
} while (1); 

3
내 예제에서 응답 배열을 더 크게 만들 수 있습니다. 나는 그가 그냥 JSON을 다시 얻고 있었다 거대한 파일을 다운로드하지 않은 그러나 물론 심지어 JSON의 질의에 따라 메가 바이트 ... 수 있습니다 가정 한
제리 예레미야

1
저는 C 초보자이며 귀하의 대답이 정확할 수 있습니다. 하지만 답변에 대한 설명을 추가해 주시겠습니까?
boop

2
이것은 실제로 받아 들여진 답변에 대한 주석 일 뿐이며, 별도의 답변 시도로 만들어서는 안됩니다.
Michael Gaskill 16.05.05

1
여기에 추가 할 한 가지는 훌륭하지만 버퍼의 크기 (1 바이트)를 읽어야합니다. 그리고 그것을 제대로보기 위해 나는 그 print 문에서 개행 문자를 사용하지 않을 것입니다. : 다음과 같이해야bytes = recv(sockfd, response, 1023, 0)
xjsc16x

11

몇 주 동안 연구 한 후. 다음 코드를 생각해 냈습니다. SSL을 사용하여 웹 서버에 안전하게 연결하는 데 필요한 최소한의 방법이라고 생각합니다.

#include <stdio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/bio.h>

#define APIKEY "YOUR_API_KEY"
#define HOST "YOUR_WEB_SERVER_URI"
#define PORT "443"

int main() {

    //
    //  Initialize the variables
    //
    BIO* bio;
    SSL* ssl;
    SSL_CTX* ctx;

    //
    //   Registers the SSL/TLS ciphers and digests.
    //
    //   Basically start the security layer.
    //
    SSL_library_init();

    //
    //  Creates a new SSL_CTX object as a framework to establish TLS/SSL
    //  or DTLS enabled connections
    //
    ctx = SSL_CTX_new(SSLv23_client_method());

    //
    //  -> Error check
    //
    if (ctx == NULL)
    {
        printf("Ctx is null\n");
    }

    //
    //   Creates a new BIO chain consisting of an SSL BIO
    //
    bio = BIO_new_ssl_connect(ctx);

    //
    //  Use the variable from the beginning of the file to create a 
    //  string that contains the URL to the site that you want to connect
    //  to while also specifying the port.
    //
    BIO_set_conn_hostname(bio, HOST ":" PORT);

    //
    //   Attempts to connect the supplied BIO
    //
    if(BIO_do_connect(bio) <= 0)
    {
        printf("Failed connection\n");
        return 1;
    }
    else
    {
        printf("Connected\n");
    }

    //
    //  The bare minimum to make a HTTP request.
    //
    char* write_buf = "POST / HTTP/1.1\r\n"
                      "Host: " HOST "\r\n"
                      "Authorization: Basic " APIKEY "\r\n"
                      "Connection: close\r\n"
                      "\r\n";

    //
    //   Attempts to write len bytes from buf to BIO
    //
    if(BIO_write(bio, write_buf, strlen(write_buf)) <= 0)
    {
        //
        //  Handle failed writes here
        //
        if(!BIO_should_retry(bio))
        {
            // Not worth implementing, but worth knowing.
        }

        //
        //  -> Let us know about the failed writes
        //
        printf("Failed write\n");
    }

    //
    //  Variables used to read the response from the server
    //
    int size;
    char buf[1024];

    //
    //  Read the response message
    //
    for(;;)
    {
        //
        //  Get chunks of the response 1023 at the time.
        //
        size = BIO_read(bio, buf, 1023);

        //
        //  If no more data, then exit the loop
        //
        if(size <= 0)
        {
            break;
        }

        //
        //  Terminate the string with a 0, to let know C when the string 
        //  ends.
        //
        buf[size] = 0;

        //
        //  ->  Print out the response
        //
        printf("%s", buf);
    }

    //
    //  Clean after ourselves
    //
    BIO_free_all(bio);
    SSL_CTX_free(ctx);

    return 0;
}

위의 코드는 원격 서버와 TLS 연결을 설정하는 방법을 자세히 설명합니다.

중요 참고 :이 코드는 공개 키가 유효한 기관에 의해 서명되었는지 확인하지 않습니다. 유효성 검사에 루트 인증서를 사용하지 않음을 의미합니다. 이 검사를 구현하는 것을 잊지 마십시오. 그렇지 않으면 올바른 웹 사이트를 연결하고 있는지 알 수 없습니다.

요청 자체에 관해서. HTTP 요청을 직접 작성하는 것 이상입니다.

또한이 링크 에서 시스템에 openSSL을 설치하는 방법과 보안 라이브러리를 사용하도록 코드를 컴파일하는 방법에 대한 설명을 찾을 수 있습니다 .


2
좋은 설명!
Satyam Koyani 16.

아니요, 다음 변수는 포트입니다. 이미 오른쪽 포트에 연결되어 있습니다.
David Gatti

3

핸들이 추가되었습니다.
호스트 헤더를 추가했습니다.
Linux / Windows 지원 추가, 테스트 완료 (XP, WIN7).
경고 : 오류 : 인수로 호스트, 경로 또는 포트가없는 경우 "분할 오류"입니다.

#include <stdio.h> /* printf, sprintf */
#include <stdlib.h> /* exit, atoi, malloc, free */
#include <unistd.h> /* read, write, close */
#include <string.h> /* memcpy, memset */
#ifdef __linux__ 
    #include <sys/socket.h> /* socket, connect */
    #include <netdb.h> /* struct hostent, gethostbyname */
    #include <netinet/in.h> /* struct sockaddr_in, struct sockaddr */
#elif _WIN32
    #include <winsock2.h>
    #include <ws2tcpip.h>
    #include <windows.h>
    #pragma comment(lib,"ws2_32.lib") //Winsock Library

#else

#endif

void error(const char *msg) { perror(msg); exit(0); }

int main(int argc,char *argv[])
{

    int i;
    struct hostent *server;
    struct sockaddr_in serv_addr;
    int bytes, sent, received, total, message_size;
    char *message, response[4096];
    int portno = atoi(argv[2])>0?atoi(argv[2]):80;
    char *host = strlen(argv[1])>0?argv[1]:"localhost";
    char *path = strlen(argv[4])>0?argv[4]:"/";
    if (argc < 5) { puts("Parameters: <host> <port> <method> <path> [<data> [<headers>]]"); exit(0); }
    /* How big is the message? */
    message_size=0;
    if(!strcmp(argv[3],"GET"))
    {
                printf("Process 1\n");
        message_size+=strlen("%s %s%s%s HTTP/1.0\r\nHost: %s\r\n");        /* method         */
        message_size+=strlen(argv[3]);                         /* path           */
        message_size+=strlen(path);                         /* headers        */
        if(argc>5)
            message_size+=strlen(argv[5]);                     /* query string   */
        for(i=6;i<argc;i++)                                    /* headers        */
            message_size+=strlen(argv[i])+strlen("\r\n");
        message_size+=strlen("\r\n");                          /* blank line     */
    }
    else
    {
                printf("Process 2\n");
        message_size+=strlen("%s %s HTTP/1.0\r\nHost: %s\r\n");
        message_size+=strlen(argv[3]);                         /* method         */
        message_size+=strlen(path);                            /* path           */
        for(i=6;i<argc;i++)                                    /* headers        */
            message_size+=strlen(argv[i])+strlen("\r\n");
        if(argc>5)
            message_size+=strlen("Content-Length: %d\r\n")+10; /* content length */
        message_size+=strlen("\r\n");                          /* blank line     */
        if(argc>5)
            message_size+=strlen(argv[5]);                     /* body           */
    }
            printf("Allocating...\n");
    /* allocate space for the message */
    message=malloc(message_size);

    /* fill in the parameters */
    if(!strcmp(argv[3],"GET"))
    {
        if(argc>5)
            sprintf(message,"%s %s%s%s HTTP/1.0\r\nHost: %s\r\n",
                strlen(argv[3])>0?argv[3]:"GET",               /* method         */
                path,                                          /* path           */
                strlen(argv[5])>0?"?":"",                      /* ?              */
                strlen(argv[5])>0?argv[5]:"",host);            /* query string   */
        else
            sprintf(message,"%s %s HTTP/1.0\r\nHost: %s\r\n",
                strlen(argv[3])>0?argv[3]:"GET",               /* method         */
                path,host);                                    /* path           */
        for(i=6;i<argc;i++)                                    /* headers        */
            {strcat(message,argv[i]);strcat(message,"\r\n");}
        strcat(message,"\r\n");                                /* blank line     */
    }
    else
    {
        sprintf(message,"%s %s HTTP/1.0\r\nHost: %s\r\n",
            strlen(argv[3])>0?argv[3]:"POST",                  /* method         */
            path,host);                                        /* path           */
        for(i=6;i<argc;i++)                                    /* headers        */
            {strcat(message,argv[i]);strcat(message,"\r\n");}
        if(argc>5)
            sprintf(message+strlen(message),"Content-Length: %d\r\n",(int)strlen(argv[5]));
        strcat(message,"\r\n");                                /* blank line     */
        if(argc>5)
            strcat(message,argv[5]);                           /* body           */
    }
    printf("Processed\n");
    /* What are we going to send? */
    printf("Request:\n%s\n",message);
        /* lookup the ip address */

    total = strlen(message);
    /* create the socket */
    #ifdef _WIN32
WSADATA wsa;
SOCKET s;

printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
    printf("Failed. Error Code : %d",WSAGetLastError());
    return 1;
}

printf("Initialised.\n");

//Create a socket
if((s = socket(AF_INET , SOCK_STREAM , 0 )) == INVALID_SOCKET)
{
    printf("Could not create socket : %d" , WSAGetLastError());
}

printf("Socket created.\n");

server = gethostbyname(host);
serv_addr.sin_addr.s_addr = inet_addr(server->h_addr);
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(portno);
memset(&serv_addr,0,sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(portno);
memcpy(&serv_addr.sin_addr.s_addr,server->h_addr,server->h_length);
//Connect to remote server
if (connect(s , (struct sockaddr *)&serv_addr , sizeof(serv_addr)) < 0)
{
    printf("connect failed with error code : %d" , WSAGetLastError());
    return 1;
}

puts("Connected");
if( send(s , message , strlen(message) , 0) < 0)
{
    printf("Send failed with error code : %d" , WSAGetLastError());
    return 1;
}
puts("Data Send\n");

//Receive a reply from the server
if((received = recv(s , response , 2000 , 0)) == SOCKET_ERROR)
{
    printf("recv failed with error code : %d" , WSAGetLastError());
}

puts("Reply received\n");

//Add a NULL terminating character to make it a proper string before printing
response[received] = '\0';
puts(response);

closesocket(s);
WSACleanup();
    #endif
    #ifdef __linux__ 
    int sockfd;
    server = gethostbyname(host);
    if (server == NULL) error("ERROR, no such host");
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd < 0) error("ERROR opening socket");
        /* fill in the structure */
        memset(&serv_addr,0,sizeof(serv_addr));
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_port = htons(portno);
        memcpy(&serv_addr.sin_addr.s_addr,server->h_addr,server->h_length);
                /* connect the socket */
        if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
            error("ERROR connecting");
                /* send the request */

    sent = 0;
    do {
        bytes = write(sockfd,message+sent,total-sent);
        if (bytes < 0)
            error("ERROR writing message to socket");
        if (bytes == 0)
            break;
        sent+=bytes;
    } while (sent < total);
    /* receive the response */
    memset(response, 0, sizeof(response));
    total = sizeof(response)-1;
    received = 0;
    printf("Response: \n");
    do {
       printf("%s", response);
       memset(response, 0, sizeof(response));
       bytes = recv(sockfd, response, 1024, 0);
        if (bytes < 0)
           printf("ERROR reading response from socket");
       if (bytes == 0)
           break;
       received+=bytes;
    } while (1);

    if (received == total)
        error("ERROR storing complete response from socket");

    /* close the socket */
    close(sockfd);
    #endif


    free(message);

    return 0;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.