简体   繁体   English

为什么在C服务器程序中出现分段错误(但仅在某些时候)?

[英]Why am I getting a segmentation fault in my C server program (but only sometimes)?

Right now, I'm trying to write a simple client/server application in order to measure the round trip time on a LAN for TCP messages of various sizes (I'm doing the timing client side). 现在,我正在尝试编写一个简单的客户端/服务器应用程序,以测量LAN上各种大小的TCP消息的往返时间(我正在计时客户端)。 The program works fine for small packet sizes (> 1000 bytes) but I end up with a segmentation fault: 11 error for inputs of larger magnitude (10KB or greater). 该程序适用于较小的数据包大小(> 1000字节),但最终出现分段错误:较大幅度(10KB或更大)的输入出现11个错误。

int main() 
{ 
    struct sockaddr_in sin; 
    char buf[MAX_LINE]; 
    int len; 
    int s, new_s; 
    /* build address data structure */ 
    bzero((char *)& sin, sizeof( sin)); 
    sin.sin_family = AF_INET; 
    sin.sin_addr.s_addr = INADDR_ANY;
    sin.sin_port = htons( SERVER_PORT);
    /* setup passive open */ 
    if (( s = socket( PF_INET, SOCK_STREAM, 0)) < 0) { 
        perror("tcp program: socket"); 
        exit(1); 
    } 
    if (( bind(s, (struct sockaddr *)& sin, sizeof(sin))) < 0) { 
         perror("tcp program: bind"); 
         exit( 1); 
 } 
    listen(s, MAX_PENDING); 
    /* wait for connection, then receive and print text */
     while(1) { 
        socklen_t lent = (unsigned int)&len;
        if ((new_s = accept(s, (struct sockaddr *)& sin, &lent)) < 0) { 
            perror("tcp program: accept"); 
            exit( 1); 
        }


        while ((len = recv(new_s, buf, sizeof(buf), 0))){ 
            char msg[len];
            send( new_s, msg, len, 0); //echo message of same length as received message
        }
        close(new_s); 
      }      
}

Again, the goal was to measure RTT, so I wanted the client to send a message, the above server to receive it, then send back a message of equivalent size. 再次,目标是测量RTT,因此我希望客户端发送一条消息,上面的服务器接收该消息,然后发送回等效大小的消息。 I also wanted the server to continue spinning so that the client could run iteratively, sending messages of 1KB, 10KB,...1000KB, etc. However, such iterations usually result in a segmentation fault. 我还希望服务器继续旋转,以便客户端可以迭代运行,发送1KB,10KB,... 1000KB等消息。但是,此类迭代通常会导致分段错误。

Oddly enough, if I configure my client to run, for example, a single 12KB message send, the server does fine, and continues to run. 奇怪的是,如果我将客户端配置为运行,例如发送单个12KB消息,则服务器运行正常,然后继续运行。 And if I wait a couple of seconds, I can even repeatedly call my client and the server keeps up. 如果我等了几秒钟,我什至可以反复呼叫我的客户,服务器保持运转。 But if I run the single message send in rapid succession, I end up with the segfault again. 但是,如果我运行快速连续发送的单个消息,则会再次遇到段错误。

Any ideas? 有任何想法吗? I apologize in advance for any elementary errors in style or format. 对于样式或格式中的任何基本错误,我深表歉意。 This is my first real foray into the C language beyond "hello world". 这是我对“ Hello World”以外的C语言的首次真正尝试。

Thanks! 谢谢!

I don't know if this is the only part of the code that is wrong, but this is wrong: 我不知道这是否是代码中唯一出错的部分,但这是错误的:

while ((len = recv(new_s, buf, sizeof(buf), 0)))

Please read the man page for recv() , in particular (emphasis added)... 请仔细阅读recv()手册页 (添加了重点)...

These calls return the number of bytes received, or -1 if an error occurred. 这些调用返回接收到的字节数, 如果发生错误返回-1。 The return value will be 0 when the peer has performed an orderly shutdown. 当对等方执行有序关闭时,返回值将为0。

We know that networks are unreliable, and it is fairly common for recv() and friends to return errors. 我们知道网络是不可靠的,并且recv()和朋友返回错误是相当普遍的。

Additionally, variable-length arrays in C are a fairly dangerous construct, because they perform dynamic allocation on the stack. 此外,C语言中的可变长度数组是一个相当危险的构造,因为它们在堆栈上执行动态分配。 They're basically alloca() in disguise, and we know how dangerous alloca() is. 它们基本上是变相的alloca() ,我们知道alloca()有多危险。 So this bit: 所以这一点:

char msg[len]; // serious problems unless we have good bounds for len

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM