c - 从客户端接受数据时出现段错误

标签 c networking segmentation-fault

我正在尝试设置服务器,但发回 HTTP 响应对我来说很困难,我的代码出现段错误,我不知道为什么。

这是我的引用代码

我知道这是一个内存问题,但我不知道在哪里,它在 while 循环中打印到接受行。

#include <stdio.h> /* for printf() and fprintf() */
#include <sys/socket.h> /* for socket(), bind(), and connect() */
#include <arpa/inet.h> /* for sockaddr_in and inet_ntoa() */
#include <stdlib.h> /* for atoi() and exit() */
#include <string.h> /* for memset() */
#include <unistd.h> /* for close() */
//#include <sys/types.h>
#include <netdb.h>
//#include <sys/stat.h>

#define MAXPENDING 5 /* Maximum outstanding connection requests */
#define RCVBUFSIZE 2048
#define CONTENTLENGTH 20,000
void DieWithError(char *errorMessage); /* Error handling function */

void DieWithError (char *errorMessage)
{
     printf(errorMessage);
     printf("\n");
}

//void HandleTCPClient(int clntSocket); /* TCP client handling function */

int main(int argc, char *argv[])
{
     //while loop over everything
     // listen for client connect
     // bind the socket
     // accept the client Socket
     // read from socket/ parse the command
     // send an appt repsonse header and body
     // close socket
     // free memory
     // ctrl c thing where u clear all memory before terminating (optional)
     struct sockaddr_in clientData;
     struct sockaddr_in servData;
     int cSock, sSock, binder, listener, acceptor, receivedData, sentData;
     unsigned int cAddr;
     unsigned short sAddr;
     char res[1024];
     char *root;

     if (argc != 2)
     {
          printf("Usage : \n\t ./server portNumber\n");
          exit(1);
     }
     sAddr = atoi(argv[1]);
     sSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

     if (sSock < 0)
     {
          DieWithError("serv socket failed");
     }

     memset(&servData, 0 , sizeof(servData));
     servData.sin_family = AF_INET;
     servData.sin_addr.s_addr = htonl(INADDR_ANY);
     servData.sin_port = htons(sAddr);

     memset(&clientData, 0, sizeof(char));

     binder = bind(sSock, (struct sockaddr *) &servData, sizeof (servData));

     listener = listen(sSock, MAXPENDING);

     if (listener < 0)
     {
          DieWithError("listen did not work");
          exit(1);
     }

     while (1)
     {
          char buffer[RCVBUFSIZE];// = (char*) malloc(RCVBUFSIZE * sizeof(char));
          printf("oddde\n");
          //cAddr = sizeof(clientData);
          cSock = accept (sSock, (struct sockaddr *) &clientData, sizeof(clientData.sin_addr));
          printf("Client %s\n", inet_ntoa(clientData.sin_addr));
          //cSock = accept (sSock, (struct sockaddr *) &clientData, &cAddr);
          printf("oke man\n");
          receivedData = recv(cSock, buffer, RCVBUFSIZE-1, 0);
          buffer[RCVBUFSIZE] = '\0';

          if (receivedData < 0)
          {
               DieWithError("recv failure");
          }

          char *ip = (char*) malloc(strlen(argv[1]) * sizeof(char));
          char *file, *port, *temp;
          temp = argv[1];
          //port = argv[2];
          file = "/";
          if (file = strstr(temp, "/"))
          {
               ip = strndup(temp, file - temp);
          }
          else
          {
               ip = strdup(temp);
          }

          if (strcmp(file, "/index.html") == 0)
          {
               printf("HTTP/1.1 200 OK \r\n");
               fprintf("Content-Length: %s \r\n",CONTENTLENGTH);
               printf("\r\n");
          }
          else
          {
               printf("HTTP/1.1 404 NOT FOUND \r\n");
               fprintf("Content Length: %s \r\n", CONTENTLENGTH);
               printf("\r\n");
          }

          sentData = send(cSock, buffer, receivedData, 0);

          if (sentData < 0)
          {
               DieWithError("sending data failure");
          }


     }
     close (cSock);
     free(receivedData);

     return 0;
}

输出:

Segmentation fault : 11
recv() failed

代码应该发回正确的http响应消息, 我有一个 client.c,我用它来测试这段代码,如果我删除套接字线(用于测试),它似乎不会退出 while 循环,主要问题是我不明白起源的段错误的。这是我的网络入门类(class)的作业,明天就要交。

最佳答案

发布的代码会导致编译器(gcc)输出多个警告:

我如何编译发布的代码:其中“untitled.c”是我发布的代码的本地名称。

gcc    -ggdb -Wall -Wextra -Wconversion -pedantic -std=gnu11  -c "untitled.c"  

现在,编译器的输出列表:

untitled.c: In function ‘DieWithError’:
untitled.c:18:6: warning: format not a string literal and no format arguments [-Wformat-security]
      printf(errorMessage);
      ^~~~~~

untitled.c: In function ‘main’:
untitled.c:48:14: warning: conversion to ‘short unsigned int’ from ‘int’ may alter its value [-Wconversion]
      sAddr = atoi(argv[1]);
              ^~~~

untitled.c:78:67: warning: passing argument 3 of ‘accept’ makes pointer from integer without a cast [-Wint-conversion]
           cSock = accept (sSock, (struct sockaddr *) &clientData, sizeof(clientData.sin_addr));
                                                                   ^~~~~~

In file included from untitled.c:2:0:
/usr/include/x86_64-linux-gnu/sys/socket.h:232:12: note: expected ‘socklen_t * restrict {aka unsigned int * restrict}’ but argument is of type ‘long unsigned int’
 extern int accept (int __fd, __SOCKADDR_ARG __addr,
            ^~~~~~

untitled.c:82:26: warning: conversion to ‘int’ from ‘ssize_t {aka long int}’ may alter its value [-Wconversion]
           receivedData = recv(cSock, buffer, RCVBUFSIZE-1, 0);
                          ^~~~

untitled.c:95:15: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
           if (file = strstr(temp, "/"))
               ^~~~

untitled.c:97:35: warning: conversion to ‘size_t {aka long unsigned int}’ from ‘long int’ may change the sign of the result [-Wsign-conversion]
                ip = strndup(temp, file - temp);
                                   ^~~~

untitled.c:107:24: warning: passing argument 1 of ‘fprintf’ from incompatible pointer type [-Wincompatible-pointer-types]
                fprintf("Content-Length: %s \r\n",CONTENTLENGTH);
                        ^~~~~~~~~~~~~~~~~~~~~~~~~

In file included from untitled.c:1:0:
/usr/include/stdio.h:312:12: note: expected ‘FILE * restrict {aka struct _IO_FILE * restrict}’ but argument is of type ‘char *’
 extern int fprintf (FILE *__restrict __stream,
            ^~~~~~~

untitled.c:13:23: warning: passing argument 2 of ‘fprintf’ makes pointer from integer without a cast [-Wint-conversion]
 #define CONTENTLENGTH 20,000
                       ^

untitled.c:107:50: note: in expansion of macro ‘CONTENTLENGTH’
                fprintf("Content-Length: %s \r\n",CONTENTLENGTH);
                                                  ^~~~~~~~~~~~~

In file included from untitled.c:1:0:
/usr/include/stdio.h:312:12: note: expected ‘const char * restrict’ but argument is of type ‘int’
 extern int fprintf (FILE *__restrict __stream,
            ^~~~~~~

untitled.c:113:24: warning: passing argument 1 of ‘fprintf’ from incompatible pointer type [-Wincompatible-pointer-types]
                fprintf("Content Length: %s \r\n", CONTENTLENGTH);
                        ^~~~~~~~~~~~~~~~~~~~~~~~~

In file included from untitled.c:1:0:
/usr/include/stdio.h:312:12: note: expected ‘FILE * restrict {aka struct _IO_FILE * restrict}’ but argument is of type ‘char *’
 extern int fprintf (FILE *__restrict __stream,
            ^~~~~~~

untitled.c:13:23: warning: passing argument 2 of ‘fprintf’ makes pointer from integer without a cast [-Wint-conversion]
 #define CONTENTLENGTH 20,000
                       ^

untitled.c:113:51: note: in expansion of macro ‘CONTENTLENGTH’
                fprintf("Content Length: %s \r\n", CONTENTLENGTH);
                                                   ^~~~~~~~~~~~~


In file included from untitled.c:1:0:
/usr/include/stdio.h:312:12: note: expected ‘const char * restrict’ but argument is of type ‘int’
 extern int fprintf (FILE *__restrict __stream,
            ^~~~~~~

untitled.c:117:42: warning: conversion to ‘size_t {aka long unsigned int}’ from ‘int’ may change the sign of the result [-Wsign-conversion]
           sentData = send(cSock, buffer, receivedData, 0);
                                          ^~~~~~~~~~~~

untitled.c:117:22: warning: conversion to ‘int’ from ‘ssize_t {aka long int}’ may alter its value [-Wconversion]
           sentData = send(cSock, buffer, receivedData, 0);
                      ^~~~

untitled.c:91:24: warning: unused variable ‘port’ [-Wunused-variable]
           char *file, *port, *temp;
                        ^~~~

untitled.c:90:17: warning: variable ‘ip’ set but not used [-Wunused-but-set-variable]
           char *ip = (char*) malloc(strlen(argv[1]) * sizeof(char));
                 ^~

untitled.c:127:11: warning: passing argument 1 of ‘free’ makes pointer from integer without a cast [-Wint-conversion]
      free(receivedData);
           ^~~~~~~~~~~~

In file included from untitled.c:4:0:
/usr/include/stdlib.h:563:13: note: expected ‘void *’ but argument is of type ‘int’
 extern void free (void *__ptr) __THROW;
             ^~~~


untitled.c:41:12: warning: unused variable ‘root’ [-Wunused-variable]
      char *root;
            ^~~~

untitled.c:40:11: warning: unused variable ‘res’ [-Wunused-variable]
      char res[1024];
           ^~~

untitled.c:38:19: warning: unused variable ‘cAddr’ [-Wunused-variable]
      unsigned int cAddr;
                   ^~~~~

untitled.c:37:42: warning: unused variable ‘acceptor’ [-Wunused-variable]
      int cSock, sSock, binder, listener, acceptor, receivedData, sentData;
                                          ^~~~~~~~

untitled.c:37:24: warning: variable ‘binder’ set but not used [-Wunused-but-set-variable]
      int cSock, sSock, binder, listener, acceptor, receivedData, sentData;
                        ^~~~~~

这些警告中有一条关于使用错误的函数语法的消息:fprintf()

以及关于“int”和char*之间转换的几个警告

此类警告至关重要。

然后有很多关于未使用的变量和已设置但从未使用过的变量的警告。

关于:#define CONTENTLENGTH 20,000 逗号“,”作为数字内的分隔符无效。编译器会将其视为 20 和一些杂散值 000

在启用警告的情况下进行编译,然后修复这些警告

强烈建议阅读/理解您正在使用的每个 C 库函数的 MAN 页面。

关于c - 从客户端接受数据时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57879361/

相关文章:

C 编程多线程段错误

c - 从c中的函数返回指针

c - Arduino线性方程求解器,打印错误答案

c# - 编码双字符指针返回值

c - 从 C 中的文件名获取 MIME 类型

ios - 低级蓝牙数据包分析

networking - Haskell 网络.浏览器 HTTPS 连接

c - 段错误--信号 11

c++ - 将指针分配给特定内存地址并更改其值后出现段错误

c - tcp(内核)旁路是如何实现的?