এইচটিটিপি পোস্ট করার এবং প্রতিক্রিয়া গ্রহণের সাধারণ সি উদাহরণ


90

আমি একটি খুব সহজ সি অ্যাপ্লিকেশন তৈরি করতে চাই যা এইচটিটিপি পোস্ট করে। এটি কয়েকটি পরামিতি নেবে এবং একটি ইউআরএল তৈরি করতে এটি ব্যবহার করবে। আমি কেবল একটি সাধারণ এইচটিটিপি পোস্ট করতে এবং কার্ল ব্যবহার না করে প্রতিক্রিয়া পেতে চাই (লাইব্রেরিগুলি চালাতে প্রয়োজন এমন মেশিনে ইনস্টল করা হবে না)।

সুডোকোড:

  1. প্রক্রিয়া 2 আরগস

  2. টেমপ্লেট ইউআরএলগুলিতে আরোগুলি রাখুন: http://api.somesite.com/apikey=ARG1&command=ARG2

  3. উত্পন্ন URL এ পোস্ট করুন

  4. প্রতিক্রিয়া গ্রহণ করুন

আমার গুগল এবং এসও অনুসন্ধানগুলি এ বিষয়ে কিছুই দেয়নি।


4
আপনি কি কোনও ধরণের নেটওয়ার্ক কাঠামো ব্যবহার করেন? আপনি কোন ওএস ব্যবহার করবেন?
cnicutar

এটি কেবলমাত্র একটি বেসিক ফেডোরা বা সেন্ট বাক্স হবে। নেটওয়ার্ক ফ্রেমওয়ার্কগুলি হ'ল স্বাভাবিক সিস / সকেট, নেটডিবি, আরপা / ইনেট। শুধু libcurl না।
kmark2

4
Libcurl না। আপনি কি অন্য কোনও লাইব্রেরির সাথে যেতে ইচ্ছুক বা এটি অল-পসিক্স হতে হবে?
cnicutar

দুর্ভাগ্যক্রমে সমস্ত পসিক্স। এটি যে কোনও সিস্টেমে সম্পূর্ণ ফ্রি স্ট্যান্ডিং থাকতে হবে।
kmark2

4
আমি আপনার জন্য তৈরি একটি নমুনা পেয়েছি তবে বার্তাটি না থাকলে আপনি কেন পোষ্ট ব্যবহার করছেন তা আমি বুঝতে পারি না। যদি সমস্ত পরামিতি কোয়েরি স্ট্রিংগুলিতে থাকে তবে আপনি একটি জিইটি করতে চান না কেন?
জেরি যেরেমিয়া

উত্তর:


191

একটি বার্তার শিরোনাম অংশ এবং একটি বার্তা শরীরে একটি ফাঁকা রেখা দ্বারা পৃথক করা হয়। মেসেজ বডি না থাকলেও ফাঁকা লাইনটি সর্বদা প্রয়োজন। শিরোনামটি একটি কমান্ড দিয়ে শুরু হয় এবং মূল মান জোড়ের অতিরিক্ত লাইনগুলি একটি কোলন এবং একটি স্থান দ্বারা পৃথক করা থাকে। যদি কোনও বার্তা শৃঙ্খলা থাকে, তবে এটি আপনি যা চান তা হতে পারে।

শিরোনামের রেখাগুলি এবং শিরোনামের শেষে ফাঁকা রেখার একটি ক্যারিগ রিটার্ন এবং লাইনফিড জোড়া দিয়ে শেষ হওয়া আবশ্যক ( HTTP শিরোনাম লাইন বিরতি স্টাইল দেখুন ) why তাই লাইনগুলির শেষে \ r \ n রয়েছে।

একটি URL এর রূপ রয়েছে http://host:port/path?query_string

কোনও ওয়েবসাইটে অনুরোধ জমা দেওয়ার দুটি প্রধান উপায় রয়েছে:

  • জিইটি: ক্যোয়ারী স্ট্রিংটি isচ্ছিক তবে নির্দিষ্ট করা থাকলে অবশ্যই যুক্তিসঙ্গতভাবে সংক্ষিপ্ত হতে হবে। এই কারণে শিরোনামটি কেবল জিইটি কমান্ড হতে পারে এবং অন্য কিছুই নয়। একটি নমুনা বার্তা হতে পারে:

    GET /path?query_string HTTP/1.0\r\n
    \r\n
    
  • পোস্ট: ক্যোয়ারী স্ট্রিংয়ের মধ্যে সাধারণত কী হবে তা পরিবর্তে বার্তার মূল অংশে রয়েছে। এ কারণে শিরোনামটির বিষয়বস্তুর ধরণ: এবং সামগ্রী-দৈর্ঘ্য: বৈশিষ্ট্য পাশাপাশি POST কমান্ড অন্তর্ভুক্ত করা দরকার। একটি নমুনা বার্তা হতে পারে:

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

সুতরাং, আপনার প্রশ্নের উত্তর দেওয়ার জন্য: আপনি যে URL টি পোস্ট করতে আগ্রহী তা হ'ল http://api.somesite.com/apikey=ARG1&command=ARG2 তবে কোনও বডি বা কোয়েরি স্ট্রিং নেই এবং ফলস্বরূপ, পোস্টের কোনও কারণ নেই কারণ সেখানে বার্তাটির শরীরে রাখার মতো কিছুই নয় এবং তাই সামগ্রী-ধরণের: এবং সামগ্রী-দৈর্ঘ্যের মধ্যে রাখার মতো কিছুই নয়:

আমার ধারণা আপনি যদি সত্যিই চান তবে আপনি পোস্ট করতে পারেন could সেক্ষেত্রে আপনার বার্তাটি দেখতে এমন হবে:

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

সুতরাং বার্তাটি প্রেরণের জন্য সি প্রোগ্রামের প্রয়োজন:

  • একটি সকেট তৈরি করুন
  • আইপি ঠিকানা অনুসন্ধান
  • সকেট খুলুন
  • অনুরোধ পাঠান
  • প্রতিক্রিয়া জন্য অপেক্ষা করুন
  • সকেট বন্ধ করুন

প্রেরণ ও প্রাপ্ত কলগুলি আপনার প্রয়োজনীয় সমস্ত ডেটা প্রেরণ / গ্রহণ করবে না - তারা প্রকৃতপক্ষে প্রেরিত / প্রাপ্ত বাইটের নম্বর ফিরিয়ে দেবে। এগুলিকে একটি লুপে কল করা এবং বার্তার বাকী পাঠানো / গ্রহণ করা আপনার পক্ষে।

আমি এই নমুনায় যা করিনি তা হ'ল কোনও ধরণের আসল ত্রুটি যাচাই করা - যখন কিছু ব্যর্থ হয় আমি কেবল প্রোগ্রামটি থেকে প্রস্থান করি। যদি তোমার জন্য এটি কাজ করে, তাহলে আমাকে জানাও:

#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 বাইট খুব বড় প্রতিক্রিয়া নয়। আপনার অনুরোধের প্রতিক্রিয়া স্বল্প হবে বলে ধরে নিয়ে আমি এ সংখ্যাটি এলোমেলোভাবে বেছে নিয়েছি। যদি এটি বড় হতে পারে তবে আপনার দুটি পছন্দ আছে:

  • সামগ্রী-দৈর্ঘ্য: প্রতিক্রিয়া থেকে শিরোনাম পড়ুন এবং তারপরে গতিশীলভাবে পুরো প্রতিক্রিয়াটি ধরে রাখতে পর্যাপ্ত মেমরি বরাদ্দ করুন।
  • টুকরা আসার সাথে সাথে একটি ফাইলের প্রতিক্রিয়া লিখুন

মন্তব্যে জিজ্ঞাসিত প্রশ্নের উত্তরের জন্য অতিরিক্ত তথ্য:

আপনি যদি বার্তাটির শরীরে ডেটা পোস্ট করতে চান তবে? তারপরে আপনাকে সামগ্রী-প্রকার: এবং সামগ্রী-দৈর্ঘ্য: শিরোনাম অন্তর্ভুক্ত করতে হবে। সামগ্রী-দৈর্ঘ্য: হ'ল শিরোনামটি শরীরে পৃথক করার পরে ফাঁকা রেখার পরে সমস্ত কিছুর আসল দৈর্ঘ্য।

এখানে একটি নমুনা যা নিম্নলিখিত কমান্ড লাইন আর্গুমেন্ট গ্রহণ করে:

  • হোস্ট
  • বন্দর
  • কমান্ড (GET বা পোস্ট)
  • পাথ (ক্যোয়ারী ডেটা সহ নয়)
  • ক্যোয়ারী ডেটা (জিইটি-র জন্য ক্যোরিয় স্ট্রিংয়ে এবং পোষ্টের জন্য শরীরে theোকানো)
  • শিরোনামের তালিকা (সামগ্রী-দৈর্ঘ্য: 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;
}

ডাকা হলে কোন যুক্তি পাস করা উচিত?
সান্তিয়াগো মার্টে অলব্রিচ

আপনাকে এমন কিছু পাস করতে হবে যা প্রথম প্যারামিটার হিসাবে অ্যাপিকে হিসাবে ব্যবহৃত হবে এবং দ্বিতীয় প্যারামিটারের কিছু যা কমান্ড হিসাবে ব্যবহৃত হবে pass আপনি যদি সম্পূর্ণ আলাদা ক্যোয়ারী স্ট্রিং ব্যবহার করতে চান তবে আপনাকে ফর্ম্যাট স্ট্রিং, প্যারামিটারের সংখ্যা এবং ব্যবহার বার্তা পরিবর্তন করতে হবে।
জেরি যেরেমিয়া

4
এই কোডটি একটি ত্রুটিযুক্ত HTTP অনুরোধ প্রকাশ করে em এইচটিটিপি নির্দিষ্ট করে যে অনুরোধ লাইনগুলি অবশ্যই ক্যারেজ-রিটার্ন / লাইন-ফিড জোড়া ( \r\n) দ্বারা শেষ করা উচিত , তবে এই কোডটি খালি লাইন ফিড ব্যবহার করে।
জন বলিঞ্জার

@ জনবোলিংগার এটি সত্য। এটা ইশারা জন্য ধন্যবাদ। আশা করি সম্পাদিত উত্তরটি আরও ভাল।
জেরি যেরেমিয়া

এই পোস্টের বার্তাটিতে কী দোষ আছে? "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"নাম = রেজার মতো পোস্ট করতে চাই। এটি 400 খারাপ অনুরোধের প্রতিক্রিয়া জানায়
রিজ মুর্শেদ

12

জেরির উত্তর দুর্দান্ত। তবে এটি বড় প্রতিক্রিয়া পরিচালনা করে না। এটি হ্যান্ডেল করার জন্য একটি সাধারণ পরিবর্তন:

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); 

4
আপনি কেবলমাত্র আমার উদাহরণটিতে প্রতিক্রিয়াটিকে আরও বড় করতে পারেন। আমি ধরে নিচ্ছিলাম যে সে সবেমাত্র কিছু জসন ফিরে পেয়েছে এবং একটি বিশাল ফাইল ডাউনলোড করছে না তবে অবশ্যই জেসন কোয়েরির উপর নির্ভর করে মেগাবাইট হতে পারে ...
জেরি যেরেমিয়া

4
আমি একজন সি শিবা এবং আপনার উত্তরটি সঠিক হতে পারে। তবে আপনি কি দয়া করে আপনার উত্তরের একটি ব্যাখ্যা যুক্ত করতে পারেন?
বুড়ো

4
এটি সত্যিকার অর্থে গ্রহণযোগ্য উত্তরের উপর একটি মন্তব্য, এবং উত্তর দেওয়ার আলাদা চেষ্টা হিসাবে করা উচিত হয়নি।
মাইকেল গসকিল

4
এখানে কেবল একটি জিনিস যুক্ত করার জন্য, এটি দুর্দান্ত কাজ করে তবে আপনার বাফার - 1 বাইটের আকারটি পড়া উচিত। এবং এটি সঠিকভাবে দেখতে আমি সেই মুদ্রণ বিবৃতিতে একটি নতুন লাইন ব্যবহার করব না। এর মতো দেখতে হবে:bytes = recv(sockfd, response, 1023, 0)
xjsc16x

11

গবেষণা কয়েক সপ্তাহ পরে। আমি নীচের কোডটি নিয়ে এসেছি। আমি বিশ্বাস করি কোনও ওয়েব সার্ভারের সাথে এসএসএলের সাথে সুরক্ষিত সংযোগ স্থাপনের জন্য এটি সর্বনিম্ন প্রয়োজনীয়।

#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;
}

উপরের কোডটি কীভাবে একটি রিমোট সার্ভারের সাথে টিএলএস সংযোগ স্থাপন করবেন তা বিশদে ব্যাখ্যা করবে।

গুরুত্বপূর্ণ দ্রষ্টব্য : এই কোডটি জন-কীটি কোনও বৈধ কর্তৃপক্ষের দ্বারা স্বাক্ষর করেছে কিনা তা পরীক্ষা করে না। মানে আমি বৈধতার জন্য মূল শংসাপত্রগুলি ব্যবহার করি না। এই চেকটি কার্যকর করতে ভুলবেন না অন্যথায় আপনি সঠিক ওয়েবসাইটটি সংযুক্ত করছেন কিনা তা আপনি জানতে পারবেন না

এটি অনুরোধ নিজেই আসে যখন। এটি হাতে হাতে এইচটিটিপি অনুরোধ লেখার পরে আর কিছুই নয়।

আপনি এই লিঙ্কের নীচে আপনার সিস্টেমে কীভাবে ওপেনএসএসএল ইনস্টল করবেন এবং কীভাবে কোডটি সংকলন করবেন সে সম্পর্কে একটি সুরক্ষা ব্যাখ্যা পেতে পারেন যাতে এটি সুরক্ষিত লাইব্রেরি ব্যবহার করে ।


4
সুন্দর ব্যাখ্যা!
সত্যম কোয়ানি

না, পরবর্তী ভেরিয়েবলটি হ'ল বন্দর, আমরা ইতিমধ্যে সঠিক বন্দরটিতে সংযোগ করছি।
ডেভিড গাট্টি

3

হ্যান্ডেল যুক্ত হয়েছে।
হোস্ট শিরোনাম যুক্ত হয়েছে।
যুক্ত লিনাক্স / উইন্ডোজ সমর্থন, পরীক্ষিত (এক্সপি, ডাব্লুআইএন 7)।
সতর্কতা: ত্রুটি: আর্গুমেন্ট হিসাবে কোনও হোস্ট, পথ বা পোর্ট না হলে "সেগমেন্টেশন ফল্ট"।

#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.