×

Loading...
Ad by
  • 推荐 OXIO 加拿大高速网络,最低月费仅$40. 使用推荐码 RCR37MB 可获得一个月的免费服务
Ad by
  • 推荐 OXIO 加拿大高速网络,最低月费仅$40. 使用推荐码 RCR37MB 可获得一个月的免费服务

没有使用到线程, 整个主程序是在一个循环里, 侦听, 接受请求, 处理请求, 关闭SOCKET, 主要代码见内

本文发表在 rolia.net 枫下论坛for(;;) {

new_sock = accept(sockfd,(struct sockaddr *)&remote, &addrlen);

if (new_sock < 0) {
perror("Error on accept");
exit(1);
}

printf("\nConnection from host %s, port %d, socket %d\n",
inet_ntoa(remote.sin_addr), ntohs(remote.sin_port),new_sock);


//start to process incoming data
bzero(buf, BUFSIZ);
/*process the data*/
bytesread = read(new_sock, buf, sizeof(buf) - 1);

if (bytesread <= 0) {
if (close(new_sock))
perror("close");
continue;
}

//construct request structure from client
struct acp_server request;
request.command = buf;
request.arg1 = buf + strlen(request.command) + 1;
request.arg2 = buf + strlen(request.command) + 1 + strlen(request.arg1) + 1;

printf("command = %s\n", request.command);
printf("arg1 = %s\n", request.arg1);
printf("arg2 = %s\n", request.arg2);

//process client request
process_client_request(request, new_sock);

//close socket when finsih client request
if (close(new_sock))
perror("close");

}

在process_client_request 这个函数里处理, 打开文件, 读取文件的数据并通过SOCKET送到客户端, 数据发送完后, 使用fclose 关闭文件句柄,
process_client_request 函数退出后, 关闭SOCKET,接着又开始下一次的循环。更多精彩文章及讨论,请光临枫下论坛 rolia.net
Report

Replies, comments and Discussions:

  • 工作学习 / 学科技术讨论 / "Too many open files" 错误,请教Linux C 编程问题。
    我在Linux 下用C 写个SOCKET SERVER 程序, 每次处理一个SOCKET CLIENT的连接请求, 并发送数据给SOKCET CLIENT.

    这个程序SOKCET SERVER 程序调用如下的一些系统函数:
    1. 文件目录操作函数
    fopen,fclose,fread, fseek,opendir, readdir, stat,closedir,chdir,

    2. socket 操作函数
    accept, read, write, close.

    这个SOCKET SERVER 程序 运行了几天后, 就出现了 "Too many open files" 错误,我查了代码, 每次文件或SOCKET 打开用完后, 都调用了fclose 或close ,不清楚还有什么原因引起的这个错误。
    • 好久没有C, 都快忘干净了. 1. fclose和close不一样, 关了socket并不能关文件; 2. 注意close的顺序, 如果先关了socket, 再关文件, 是不是就关不了了...
    • 用lsof查看
      • 应为是tiny linux, 没有lsof这个命令
        • 将你的程序放到有lsof, fuser机器上调试好了
          How to use lsof or fuser:

          method 1: lsof | grep /mnt/disk [find process using that device]
          Then you can try to kill the process

          method 2: fuser -muv /mnt/disk [list the process using the file or socket]
    • fork了么?
      • 没有使用到线程, 整个主程序是在一个循环里, 侦听, 接受请求, 处理请求, 关闭SOCKET, 主要代码见内
        本文发表在 rolia.net 枫下论坛for(;;) {

        new_sock = accept(sockfd,(struct sockaddr *)&remote, &addrlen);

        if (new_sock < 0) {
        perror("Error on accept");
        exit(1);
        }

        printf("\nConnection from host %s, port %d, socket %d\n",
        inet_ntoa(remote.sin_addr), ntohs(remote.sin_port),new_sock);


        //start to process incoming data
        bzero(buf, BUFSIZ);
        /*process the data*/
        bytesread = read(new_sock, buf, sizeof(buf) - 1);

        if (bytesread <= 0) {
        if (close(new_sock))
        perror("close");
        continue;
        }

        //construct request structure from client
        struct acp_server request;
        request.command = buf;
        request.arg1 = buf + strlen(request.command) + 1;
        request.arg2 = buf + strlen(request.command) + 1 + strlen(request.arg1) + 1;

        printf("command = %s\n", request.command);
        printf("arg1 = %s\n", request.arg1);
        printf("arg2 = %s\n", request.arg2);

        //process client request
        process_client_request(request, new_sock);

        //close socket when finsih client request
        if (close(new_sock))
        perror("close");

        }

        在process_client_request 这个函数里处理, 打开文件, 读取文件的数据并通过SOCKET送到客户端, 数据发送完后, 使用fclose 关闭文件句柄,
        process_client_request 函数退出后, 关闭SOCKET,接着又开始下一次的循环。更多精彩文章及讨论,请光临枫下论坛 rolia.net
        • 把这里面的东东贴出来看一下:process_client_request(request, new_sock)
        • 运行netstat 看看你的socket 处在什么状态。 另外你read from client部分有问题。你不能确保request 全部被读了。
          • 你不能确保request 全部被读 - 这个应该不会导致too many file open.
            • If there are un-read data in buffer, then FIN will be ignored. so if the client send the FIN first Server will never close it's socket.
            • and if the client code has the same Read/Write logic problem, then the FIN (close()) will be ignored by client, and the Server socket's will remain in FIN_WAIIT_2 states for ever.
        • 另外我猜测你的server 上处理client 请求的socket们应该处在FIN_WAIT_2状态,如果是的话,修改你Server/Client部分的read/write部分
          • server 上的accept后的socket seems already closed correctly.
            • so I suspect problem in function process_client_request().
              • 我感觉是socket部分有问题
            • how could you know they are closed? close() does not mean the SOCKET has been changed to CLOSED state.
    • increase value of maximum open files.
      The default vaule is 1024. you can increase the value.
      ulimit -n : show 1024

      increase the value in file /etc/security/limits.conf

      item: nofile, ---follow instructions on comment lines.
    • 谢谢大家的回复,发现代码的有个地方使用到opendir, 用完后忘记使用closedir, 现在改过后的程序还在运行, 需等几天才能出结果。
      • 编程风格有问题,这种成对使用的函数,一开始,就把写一对,省的后来忘了。