在本地测试TCP / IP服务器

时间:2019-01-08 23:46:45

标签: c sockets tcp netcat tcpserver

我已经用C语言编写了一个echo TCP服务器。

我希望测试我的代码,看看它是否有效。

#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");

   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
         char buf[BUF_SIZE];
         while(1){
             ssize_t nread = recv(cfd, buf, BUF_SIZE, 0);
             if (nread == 0) {
                 close(cfd);
                 exit(EXIT_SUCCESS);
             } else {
                 ssize_t nsent = send(cfd, buf, nread, 0);
                 if (nsent != nread) fprintf(stderr, "Error sending response");
             }

         }
      } else {
         //Parent code

      }
   }
   close(sfd);
} 

它可以正常编译,但是当我尝试以tcp_server 127.0.0.1 80的身份运行它时,会显示错误消息Could not bind to any socket

据我了解,这应该将服务器绑定到IPv4环回地址(端口80),然后我就可以使用netcat与它进行交互了。

这是怎么回事?

2 个答案:

答案 0 :(得分:1)

大多数操作系统认为低编号的端口具有特权。尝试使用8000或8080这样的端口。

答案 1 :(得分:0)

由于您要通过命令行参数(即ARGV [2])传递端口80,端口号80是分配给常用Internet通信协议即超文本传输​​协议(HTTP)的端口号。

您可以根据以下分类使用端口:  1.端口0–1023 –系统或知名端口  2.端口1024–49151 –用户或注册端口  3.端口> 49151 –动态/专用端口

因此,这样可能会解决您的问题。