解除绑定端口

时间:2019-01-09 08:46:27

标签: c sockets tcp port

我从终端启动了一个绑定了某些端口的进程。

问题代码是这样的:

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

#define BUF_SIZE 500
#define LISTEN_BACKLOG 50

#define handle_error(msg) \
   do { perror(msg); exit(EXIT_FAILURE); } while (0)

int
main(int argc, char *argv[])
{
   struct addrinfo hints;
   struct addrinfo *res, *rp;
   struct sockaddr_storage peer_addr;
   socklen_t peer_addr_len;
   int sfd, cfd;

   if(argc != 3) {
      fprintf(stderr, "Usage: %s address port\n", argv[0]);
      exit(EXIT_FAILURE);
   }

   memset(&hints, 0, sizeof(struct addrinfo));
   hints.ai_family = AF_UNSPEC;
   hints.ai_socktype = SOCK_STREAM;
   hints.ai_flags = AI_PASSIVE;
   hints.ai_protocol = 0;
   hints.ai_addr = NULL;
   hints.ai_next = NULL;

   if(getaddrinfo(argv[1], argv[2], &hints, &res) != 0)
      handle_error("getaddrinfo");

   // Try each socket until we bind
   for(rp = res; rp != NULL; rp = rp->ai_next){
      sfd = socket(rp->ai_family, rp->ai_socktype, 0);
      if(sfd == -1) continue;
      if(bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0) break;
      else close(sfd);
   }

   freeaddrinfo(res);

   if (rp == NULL){
      fprintf(stderr, "Could not bind to any socket\n");
      exit(EXIT_FAILURE);
   }

   // Set the TCP socket to listen state
   if (listen(sfd, LISTEN_BACKLOG) == -1) handle_error("listen");

   printf("Server started");

   for(;;){
      // Accept
      peer_addr_len = sizeof(struct sockaddr_storage);
      cfd = accept(sfd, (struct sockaddr *) &peer_addr, &peer_addr_len);
      if (cfd == -1) handle_error("accept");

      // Fork
      pid_t pid = fork();

      if (pid == 0){ //Child code
         pid_t my_pid = getpid();
         char buf[BUF_SIZE];
         while(1){
             ssize_t nread = recv(cfd, buf, BUF_SIZE, 0);
             if (nread == 0) {
                 close(cfd);
                 exit(EXIT_SUCCESS);
             } else {
                 buf[nread] = 0;
                 fprintf(stdout, "Worker %i has received a message: %s", my_pid, buf);
                 ssize_t nsent = send(cfd, buf, nread, 0);
                 if (nsent != nread) fprintf(stderr, "Error sending response");
             }

         }
   }
   close(sfd);
}

调用代码后,我终止了该进程,并注意到无法使用同一端口两次运行该程序。

我检查了sudo lsof -i -P -n | grep LISTEN,它列出了我用于测试的端口处于LISTEN状态,而我的程序正是造成这种情况的罪魁祸首。

如何解除端口绑定?如何修改我的代码,以便在接收到合适的信号后将其自身解除绑定?

0 个答案:

没有答案
相关问题