2

我已经尝试运行我的代码一周了,但我不知道问题是什么。在我的编程课程中,我们获得了一个代码,允许我们制作自己的 tcp 客户端和/或服务器。使用该代码,我们必须打开 localhost:54321 [我们使用 Apache 作为我们的本地服务器,如果这有助于/提供对正在发生的事情的更好理解] 并通过调整服务器的 C 代码,页面将显示一条消息。

这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>



int main(int argc, char **argv)
{
  int listenfd,connfd;
  struct sockaddr_in servaddr,cliaddr;
  socklen_t len = sizeof(cliaddr);
  char cli_ip[32];
  char mesg[1024];
  char response[1028];
  //char reply[] = "Hello World!";

  listenfd = socket(PF_INET,SOCK_STREAM,0);
  bzero(&servaddr, sizeof(servaddr));
  servaddr.sin_family = AF_INET;
  servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  servaddr.sin_port = htons(54321);

  if ( bind( listenfd, (struct sockaddr*) &servaddr, sizeof(servaddr) ) < 0 ){
      perror(NULL);
      exit(-1);
  }

  while(1){
    //not present in udp server
    connfd = accept(listenfd,(struct sockaddr *)&cliaddr,&len);
    inet_ntop(AF_INET,(struct in_addr *) &cliaddr.sin_addr, cli_ip, sizeof(cli_ip) );
    printf("Client %s connected. \n",cli_ip);

    while(1){
      memset(mesg,0,sizeof(mesg));
      if( recvfrom(connfd,mesg,sizeof(mesg),0,(/*const*/ struct sockaddr *)&cliaddr,&len) > 0 ){
            printf("From %s port %d: %s",cli_ip,ntohs(cliaddr.sin_port),mesg);
        **sprintf(response,"HTTP/1.1 200 OK \n Content-type:text/html \n Content-length: 200 \r\n <html><body> Hello, World! </body></html>");
        sendto(connfd,response,strlen(response),0,(const struct sockaddr *)&servaddr,len);
        //break;**
      }
      else {
        printf("Client %s disconnected.\n",cli_ip);   
        break;
      }
    }

    close(connfd);
  }

  close(listenfd);

  return 0;
}

我添加的唯一行是粗体/用双星号括起来的行。

我可以编译它,我可以运行它,但是当我打开 localhost:54321 时,我说正在连接,但它永远不会完成加载/连接。

如果有帮助,这就是我打开 localhost:54321 时终端显示的内容。

Client 127.0.0.1 connected. 
From 127.0.0.1 port 42642: GET / HTTP/1.1
Host: localhost:54321
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:22.0) Gecko/20100101 Firefox/22.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive

感谢您的任何意见、建议、想法和批评。

4

2 回答 2

1

HTTP 要求行以 CRLF ( \r\n) 结尾。您的代码仅使用\n可能会混淆一些基本 Web 客户端的内容。

更重要的是,您还需要使用额外的 CRLF 终止响应中的标头,并且标头中的值Content-length必须与标头之后发送的字节数匹配。

就像是

const char* entity = "<html><body> Hello, World! </body></html>";
sprintf(response,"HTTP/1.1 200 OK\r\n Content-type:text/html\r\n Content-length: %d\r\n\r\n%s", strlen(entity), entity);

应该解决这个问题。

于 2013-08-29T11:13:34.493 回答
1

您需要在标题和消息正文之间有一个空行。

此外,您提供的内容长度为 200,但事实并非如此,因此浏览器正在等待其余数据。

于 2013-08-29T11:16:13.250 回答