একটি বার্তার শিরোনাম অংশ এবং একটি বার্তা শরীরে একটি ফাঁকা রেখা দ্বারা পৃথক করা হয়। মেসেজ বডি না থাকলেও ফাঁকা লাইনটি সর্বদা প্রয়োজন। শিরোনামটি একটি কমান্ড দিয়ে শুরু হয় এবং মূল মান জোড়ের অতিরিক্ত লাইনগুলি একটি কোলন এবং একটি স্থান দ্বারা পৃথক করা থাকে। যদি কোনও বার্তা শৃঙ্খলা থাকে, তবে এটি আপনি যা চান তা হতে পারে।
শিরোনামের রেখাগুলি এবং শিরোনামের শেষে ফাঁকা রেখার একটি ক্যারিগ রিটার্ন এবং লাইনফিড জোড়া দিয়ে শেষ হওয়া আবশ্যক ( 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[])
{
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); }
sprintf(message,message_fmt,argv[1],argv[2]);
printf("Request:\n%s\n",message);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) error("ERROR opening socket");
server = gethostbyname(host);
if (server == NULL) error("ERROR, no such host");
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);
if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
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);
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(sockfd);
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;
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); }
message_size=0;
if(!strcmp(argv[3],"GET"))
{
message_size+=strlen("%s %s%s%s HTTP/1.0\r\n");
message_size+=strlen(argv[3]);
message_size+=strlen(argv[4]);
if(argc>5)
message_size+=strlen(argv[5]);
for(i=6;i<argc;i++)
message_size+=strlen(argv[i])+strlen("\r\n");
message_size+=strlen("\r\n");
}
else
{
message_size+=strlen("%s %s HTTP/1.0\r\n");
message_size+=strlen(argv[3]);
message_size+=strlen(argv[4]);
for(i=6;i<argc;i++)
message_size+=strlen(argv[i])+strlen("\r\n");
if(argc>5)
message_size+=strlen("Content-Length: %d\r\n")+10;
message_size+=strlen("\r\n");
if(argc>5)
message_size+=strlen(argv[5]);
}
message=malloc(message_size);
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",
strlen(argv[4])>0?argv[4]:"/",
strlen(argv[5])>0?"?":"",
strlen(argv[5])>0?argv[5]:"");
else
sprintf(message,"%s %s HTTP/1.0\r\n",
strlen(argv[3])>0?argv[3]:"GET",
strlen(argv[4])>0?argv[4]:"/");
for(i=6;i<argc;i++)
{strcat(message,argv[i]);strcat(message,"\r\n");}
strcat(message,"\r\n");
}
else
{
sprintf(message,"%s %s HTTP/1.0\r\n",
strlen(argv[3])>0?argv[3]:"POST",
strlen(argv[4])>0?argv[4]:"/");
for(i=6;i<argc;i++)
{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");
if(argc>5)
strcat(message,argv[5]);
}
printf("Request:\n%s\n",message);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) error("ERROR opening socket");
server = gethostbyname(host);
if (server == NULL) error("ERROR, no such host");
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);
if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
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);
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(sockfd);
printf("Response:\n%s\n",response);
free(message);
return 0;
}