我有简单的TCP服务器程序。在我使用CTRL+C关闭它并在某些情况下再次重新启动后,telnet客户端会向我报告"connection refused"。为什么它不总是发生,而只是在某些情况下发生?命令ps与我的程序无关。

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include<string.h>

void printHex(char *bts);

int main() {
    char str[100];
    int listen_fd, comm_fd;
    struct sockaddr_in servaddr;
    listen_fd = socket(AF_INET, SOCK_STREAM, 0);
    bzero( &servaddr, sizeof(servaddr));

    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htons(INADDR_ANY);
    servaddr.sin_port = htons(22000);
    printf("binding\n");
    bind(listen_fd, (struct sockaddr *) &servaddr, sizeof(servaddr));

    printf("listening\n");
    listen(listen_fd, 10);

    printf("accepting\n");
    comm_fd = accept(listen_fd, (struct sockaddr*) NULL, NULL);
    printf("accep done\n");

    int cn = 0;

    while(1) {
        bzero(str, 100);
        printf("will read\n");
        int br = read(comm_fd, str, 100);
        printf("read done\n");
        if (br > 0) {
            printHex(str);
        } else if (br <= 0) {
            comm_fd = accept(listen_fd, (struct sockaddr*) NULL, NULL);
            printf("accep done\n");
        }
        printf("error %d \n", br);
   }
}

void printHex(char *bts) {
    char *s = bts;
    int i = 0;
    do {
        printf("%02X ", (unsigned char) *bts);
    } while (*++bts !=0);
    printf("%s\n",s);
}

最佳答案

您应该检查系统调用中的所有返回值:

int res;

res = bind(listen_fd, (struct sockaddr *) &servaddr, sizeof(servaddr));
if (res == -1)
  // handle error
listen_fd = socket(AF_INET, SOCK_STREAM, 0);
if (listed_fd == -1)
  // handle error

很有可能您会发现代码在bind系统调用上失败,这意味着您无法在相同的IP地址,协议(protocol)和端口上重用套接字。您可以使用setsockopt调用来更改此设置:
// allow to rebind
int reuseaddr_on = 1;
res = setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR,
            &reuseaddr_on, sizeof(reuseaddr_on));
if (res < 0)
{
    stderr("Setting of SO_REUSEADDR on server's"
                            "socket failed");
}

完成后,还应该关闭套接字。
while(1)
{
  //  your loop
}
res = close(comm_fd);
if (res == -1)
  // handle error

正如Linux程序员手册在专门介绍结束调用的页面上所说的那样:

关于c - 与 socket 的连接被拒绝,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34494332/

10-12 06:51