首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >挂掉HTTP /请求

挂掉HTTP /请求
EN

Stack Overflow用户
提问于 2015-01-25 05:19:59
回答 1查看 341关注 0票数 0

我不知道我的程序在哪里/怎么被挂掉。我很有信心这是在发送或接收链接..。但是,即使在网上搜索了一些帮助,也得到了我的教授的帮助,我仍然迷失了,为什么这是行不通的。

代码语言:javascript
复制
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#define LENGTH 500 

int main(int argc, char** argv) 
{   
  // holds the value of the command-line argument
  char link[LENGTH]; 
  strcpy (link , argv[1]);  
  printf ("%s\n", link); 

  // break up link into the host and path -- use the "/"
  char _host[LENGTH];
  char _path[LENGTH]; 
  int slashCount = 0;
  int i; 

  for (i=0 ; i<strlen(link); i++)
  {
    printf ("%c , slashcount: %d\n", link[i], slashCount);
    if (link[i] == '/') slashCount ++; 
    if (slashCount > 2)
    {
       // i is at the end of the host   
       strncpy (_host , link , i);
       _host[i] = '\0';
       break; 
    }

  } // end for

 if (slashCount == 2)
 {
    // given only a host, copy the entire string into the host
   strncpy(_host, link, i); 
   _host[i] = '\0'; 
 }

 else  // get the path for slashCount of 3 
 {
   for (i ; strlen(link); i++ )
   {
       strcat (_path, &link[i]);
       // if slash at the end of host name 
       if (strlen(_path) == 1)
       {
           // set the file field to be index.html
           char t[11] = {'i','n','d','e','x','.','h','t','m','l','\0'}; 
           for (int c=0; c< 10 ; c++)
           strncpy(_path, t, 11);
       }
       break; 
   }
 } // end if/else 

 printf ("%s\n" , _host); /*success*/
 printf ("%s\n" , _path); /*success*/ 

 struct addrinfo hints;
 struct addrinfo * result, * rp;
 int sock_fd, s;

 hints.ai_socktype = SOCK_STREAM;
 memset(&hints,0,sizeof(struct addrinfo)); // setting the values to 0 

 s = getaddrinfo("::1","http", &hints,&result); /////////////// 
 if (0 != s)
 {
   perror("error populating address structure");
   exit(1);
 }
 printf ("entering tcp setup connections"); 

 // check the host name’s IP address — has a dynamic configuration(DNS)
 // but does not change very frequently 
 for (rp = result; rp != NULL; rp = rp->ai_next) 
 {
   sock_fd = socket(rp->ai_family, rp->ai_socktype,
    rp->ai_protocol);
   if (sock_fd == -1)
      continue;

   if (connect(sock_fd, rp->ai_addr, rp->ai_addrlen) != -1)
     break; 

   close(sock_fd);
 }

 if (rp == NULL) 
 {
   // you didn’t find a good ip address to connect with 
   fprintf(stderr, "could not connect\n");
   exit(1);
 } // end for 

 freeaddrinfo(result);

 // sending the request
 sprintf (link, "GET %s HTTP/1.0\r\n" "Host: %s\r\n\r\n", _path,    _host);  
 if (send (sock_fd, link, strlen(link), 0 )< 0)
   fprintf (stderr, "Error with send\n"); 
 else 
   fprintf (stderr, "Successfully send the fetch request\n");  

 // responding to the send 
 char buf[500];
 memset(&buf,0,sizeof(buf));
  /*  int recv_count = recv(sock_fd, buf, 500, 0);

 if(recv_count<0) 
 { 
   perror("Receive failed");    
   exit(1); 
 }

 printf("%s",buf); */                   
/*  while (0 > recv (sock_fd, buf, 500, 0))
 {
    printf ("%s", buf); 
 }
 shutdown(sock_fd,SHUT_RDWR); */ 
 exit (1); 
}

我知道我必须发送一个get请求,我注释掉了响应部分,并看到tcp连接设置中有一个成功的条目。我只是搞不懂该如何设置响应。我知道如何使用读/写,但我也想尝试发送/recv。

任何帮助都是非常感谢的。

我目前正在获得的输出:

代码语言:javascript
复制
http://google.com/
h , slashcount: 0
t , slashcount: 0
t , slashcount: 0
p , slashcount: 0
: , slashcount: 0
/ , slashcount: 0
/ , slashcount: 1
g , slashcount: 2
o , slashcount: 2
o , slashcount: 2
g , slashcount: 2
l , slashcount: 2
e , slashcount: 2
. , slashcount: 2
c , slashcount: 2
o , slashcount: 2
m , slashcount: 2
/ , slashcount: 2
http://google.com
index.html
Successfully send the fetch request
entering tcp setup connections
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-01-25 11:25:25

recv()的返回值指示Connection refused,这表明套接字的设置存在问题。

您需要颠倒这两行的顺序:

代码语言:javascript
复制
hints.ai_socktype = SOCK_STREAM;
memset(&hints,0,sizeof(struct addrinfo)); // setting the values to 0

以便在将内存设置为零之后分配ai_socktype

getaddrinfo()调用传递作为第一个参数时,从cli接收的字符串link (::1localhost的别名)。

代码语言:javascript
复制
s = getaddrinfo(link,"http", &hints,&result); ///////////////

更改代码将导致:

代码语言:javascript
复制
woof@fth ~ % ./test.o google.com        
google.com
sock_fd=3
socket opened
Successfully sent the fetch request
HTTP/1.0 404 Not Found
Content-Type: text/html; charset=UTF-8
X-Content-Type-Options: nosniff
Date: Sun, 25 Jan 2015 11:07:09 GMT
Server: sffe
Content-Length: 1425
X-XSS-Protection: 1; mode=block
Alternate-Protocol: 80:quic,p=0.02

<!DOCTYPE html>
<html lang=en>
  <meta charset=utf-8>
  <meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
  <title>Error 404 (Not Found)!!1</title>
  <style>
    *{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}%

这意味着服务器响应了。

找不到该文件,因为在行中

代码语言:javascript
复制
sprintf (link, "GET %s HTTP/1.0\r\n" "Host: %s\r\n\r\n", _path,    _host);  

请求一个不存在的路径;如果您尝试使用

代码语言:javascript
复制
sprintf (link, "GET / HTTP/1.0\n\n");  

您应该看到一些不同的东西(可能是另一个错误)。如果您想获得一个不同的路径,您需要在请求中正确地插入它(从输入字符串中识别它)。

我编译的代码几乎与您的代码相同:

代码语言:javascript
复制
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>


#define LENGTH 500 

int main(int argc, char** argv) {
    // holds the value of the command-line argument
    char link[LENGTH]; 
    strcpy (link , argv[1]);  
    printf ("%s\n", link); 

    // break up link into the host and path -- use the "/"
    char _host[LENGTH];
    char _path[LENGTH]; 
    int slashCount = 0;
    int i,c; 

    for (i=0 ; i<strlen(link); i++) {

        if (link[i] == '/')
            slashCount ++; 

        if (slashCount > 2) {
            // i is at the end of the host   
            strncpy (_host , link , i);
            _host[i] = '\0';
            break; 
        }
    }

    if (slashCount == 2) {
        // given only a host, copy the entire string into the host
        strncpy(_host, link, i); 
        _host[i] = '\0'; 
    }
    else {
        // get the path for slashCount of 3 
        for (i ; strlen(link); i++ ) {
            strcat (_path, &link[i]);
            // if slash at the end of host name 
            if (strlen(_path) == 1)
            {
                // set the file field to be index.html
                char t[11] = {'i','n','d','e','x','.','h','t','m','l','\0'}; 
                strncpy(_path, t, 11);
            }
            break; 
        }
    } // end if/else 

    struct addrinfo hints;
    struct addrinfo *result, *rp;
    int sock_fd, s;

    memset(&hints,0,sizeof(struct addrinfo)); // setting the values to 0 
    hints.ai_socktype = SOCK_STREAM; // tcp socket

    // create addrinfo structure with parameters to initialize a socket
    s = getaddrinfo("::1","8080", &hints,&result); /////////////// 

    if( s!=0 ) {
        perror("error populating address structure");
        exit(1);
    }

    char temp[5000];

    // check the host name’s IP address — has a dynamic configuration(DNS)
    // but does not change very frequently 
    for( rp=result; rp!=NULL; rp=rp->ai_next ) {
        sock_fd = socket(rp->ai_family, rp->ai_socktype,rp->ai_protocol);
        fprintf(stderr,"sock_fd=%d\n",sock_fd);

        if (sock_fd == -1)
            continue;

        // exit loop on success
        if( connect(sock_fd, rp->ai_addr, rp->ai_addrlen)==0 )
            break;
        else
            close(sock_fd);
    }

    if( rp==NULL ) {
        // you didn’t find a good ip address to connect with 
        fprintf(stderr, "could not connect\n");
        exit(1);
    }
    else
        printf("socket opened\n");

    freeaddrinfo(result);


    // formatting the request string
    sprintf (link, "GET %s HTTP/1.0\r\n" "Host: %s\r\n\r\n", _path,    _host);  
    // sending the request
    if( send(sock_fd, link, strlen(link), 0)<0 )
        fprintf(stderr, "Error with send\n");
    else 
        fprintf (stderr, "Successfully sent the fetch request\n");  

    // response buffer
    char buf[500];
    memset(&buf,0,sizeof(buf));

    int recv_count = recv(sock_fd, buf, 500, 0);

    if( recv_count<0 ){
       perror("Receive failed");    
       exit(1); 
    }

    printf("%s",buf);
/*  while (0 > recv (sock_fd, buf, 500, 0))
 {
    printf ("%s", buf); 
 }
 shutdown(sock_fd,SHUT_RDWR); */ 
    exit (0); 
}

更改函数调用并还原sprintf格式化GET请求。您应该在另一个终端上启动命令。

代码语言:javascript
复制
echo "Here is a message" | nc -l -6 8080

它暂停执行,直到在端口上收到请求为止(标志为-l,有关此问题的更多信息,请参见网猫手册 )。

请求打印在netcat终端上,进程终止,而在启动编译代码的终端上,您应该看到消息在netcat中回显和管道化。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28133501

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档