在C语言的Linux套接字编程中,服务器套接字无法关闭

时间:2017-07-07 09:01:13

标签: c linux sockets tcp

我正在学习linux中的socket编程,我遇到了问题。

我正在尝试使用TCP套接字建立一个非常简单的客户端 - 服务器套接字连接。但是,我认为我无法关闭服务器套接字,因为当我重新启动服务器时,它无法绑定到相同的IP地址和端口号。

我也不知道如何调试问题。我已经读过,当bind的手册页出现错误时,会设置errno。我不知道如何看待errno

这是我的所有代码:

#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 serverSocket, clientSocket, portno;
    socklen_t clientLength;
    struct sockaddr_in serverAddress, clientAddress;
    int n;
    char buffer[256];

    if (argc < 2) {
        fprintf(stderr, "ERROR too few arguments.\n");
        exit(-1);
    }

    serverSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (serverSocket < 0) {
        fprintf(stderr, "ERROR creating socket!\n");
        exit(1);
    }

    bzero((char*) &serverAddress, sizeof(serverAddress));
    portno = atoi(argv[1]);

    serverAddress.sin_family = AF_INET;
    serverAddress.sin_addr.s_addr = INADDR_ANY;
    serverAddress.sin_port = htons(portno);

    if (bind(serverSocket, (struct sockaddr*) &serverAddress, sizeof(serverAddress)) < 0) { //This bind will fail, after re-run.
        fprintf(stderr, "ERROR binding socket\n");
        exit(2);
    }

    listen(serverSocket, 5);
    clientLength = sizeof(clientAddress);

    clientSocket = accept(serverSocket, (struct sockaddr*) &clientSocket, &clientLength);
    if (clientSocket < 0) {
        fprintf(stderr, "ERROR on accept\n");
        exit(3);
    }

    bzero(buffer, 256);
    n = read(clientSocket, buffer, 256);
    char* ack = "I got your message";
    fprintf(stdout, "Here is the message %s\n", buffer);

    n = write(clientSocket, ack, strlen(ack));

    close(clientSocket);
    close(serverSocket);
    return 0;
}

据我所知,作为文件描述符的套接字无法立即关闭。因此,当程序终止并且我在30秒内再次运行时,它无法绑定到该地址。但是,如果我等了一分钟,它就没有问题绑定到地址。

导致此问题的原因是什么?

1 个答案:

答案 0 :(得分:0)

您可以使用perror()查看可读的错误消息,并设置serverSocket可重复使用。该片段列在此处:

serverAddress.sin_port = htons(portno);
int opt = 1;
setsockopt(serverSocket,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
if (bind(serverSocket, (struct sockaddr*) &serverAddress, sizeof(serverAddress)) < 0) {
    //This bind will fail, after re-run.
    perror("bind ");
    fprintf(stderr, "ERROR binding socket\n");
    exit(2);
}