需要帮忙用C TCP端口号和IP地址

编程入门 行业动态 更新时间:2024-10-24 18:24:39
本文介绍了需要帮忙用C TCP端口号和IP地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我试图找到一个办法让我的服务器,打印其TCP端口号和IP地址,但我怎么也得它现在是生产了错误的IP,我得到的0.0.33.32的输出。任何帮助AP preciated!

的#include<&stdio.h中GT;#包括LT&;&stdlib.h中GT;#包括LT&;&unistd.h中GT;#包括LT&;&errno.h中GT;#包括LT&;&string.h中GT;#包括LT&; SYS / types.h中>#包括LT&; SYS / socket.h中>#包括LT&; netinet / in.h中>#包括LT&;&netdb.h中GT;#包括LT&; ARPA / inet.h>#包括LT&; SYS / wait.h>#包括LT&;&signal.h中GT;#包括LT&;&time.h中GT;#定义端口21467//该端口的用户将被连接到#定义积压10 //多少挂起的连接队列将举行无效sigchld_handler(int类型){而(waitpid函数(-1,NULL,WNOHANG)大于0);}//获取套接字地址,IPv4或IPv6:无效* get_in_addr(结构sockaddr * SA){如果(SA->上sa_family == AF_INET){    返回及(((结构SOCKADDR_IN *)SA) - GT; sin_addr);}返回及(((结构* sockaddr_in6的)SA) - GT; sin6_addr);}INT主要(无效){INT的sockfd,new_fd; //监听sock_fd,在new_fd新的连接结构addrinfo中的提示,* servinfo,* P;结构sockaddr_storage their_addr; //连接器的地址信息socklen_t的sin_size;结构sigaction的SA;INT是= 1;个char [INET6_ADDRSTRLEN]INT RV;memset的(安培;提示,0,sizeof的提示);hints.ai_family = AF_UNSPEC;hints.ai_socktype = SOCK_STREAM;hints.ai_flags = AI_PASSIVE; //用我的IP烧焦hname [100];的gethostname(hname,sizeof的hname);如果((RV =的getaddrinfo(hname,PORT&放大器;提示,&放大器;!servinfo))= 0){    fprintf中(标准错误的getaddrinfo:%S \\ n,gai_strerror(RV));    返回1;}//遍历所有的结果,并结合第一个我们可以为(P = servinfo; P!= NULL; P = P-> ai_next){    如果((的sockfd =插座(对GT; ai_family,P-> ai_socktype,            P-> ai_protocol))== -1){        PERROR(服务器:套接字);        继续;    }    如果(setsockopt的(的sockfd,SOL_SOCKET,SO_REUSEADDR,&安培;是的,            的sizeof(INT))== -1){        PERROR(setsockopt的);        出口(1);    }    如果(绑定(的sockfd,P-> ai_addr,P-> ai_addrlen)== -1){        接近(的sockfd);        PERROR(服务器:绑定);        继续;    }    打破;}如果(P == NULL){    fprintf中(标准错误,服务器:无法绑定\\ n);    返回2;}freeaddrinfo(servinfo); //所有这种结构完成如果(听(的sockfd,积压)== -1){    PERROR(听);    出口(1);}sa.sa_handler = sigchld_handler; //获得全部死亡过程sigemptyset(安培; sa.sa_mask);sa.sa_flags = SA_RESTART;如果(的sigaction(SIGCHLD,&安培; SA,NULL)== -1){    PERROR(sigaction的);    出口(1);}焦炭主机[100];焦炭服务[20];则getnameinfo(对GT; ai_addr,P-> ai_addrlen,主机,sizeof的主机,服务sizeof的服务,0);inet_ntop(对GT; ai_family,get_in_addr((结构sockaddr *)&P- GT; ai_addr)        主机,主机的sizeof);的printf(服务器:有TCP端口号,%s和IP地址%S \\ N,服务,主机);的printf(服务器:等待连接... \\ n);INT的numBytes;焦炭BUF [100];而(1){//主接受()循环    sin_size = sizeof的their_addr;    new_fd =接受(的sockfd,(结构sockaddr *)及their_addr,&安培; sin_size);    如果(new_fd == -1){        PERROR(接受);        继续;    }    inet_ntop(their_addr.ss_family,        get_in_addr((结构sockaddr *)及their_addr)        S,sizeof的S);    //则getnameinfo(get_in_addr((结构sockaddr *)及their_addr),sizeof的get_in_addr((结构sockaddr *)及their_addr),NULL,NULL,服务,sizeof的服务,0);    如果((的numBytes =的recv(new_fd,buf中,100,0))== - 1)        PERROR(RECV);    / *如果((的numBytes =的recv(的sockfd,BUF,100,0))== -1){    PERROR(RECV);    出口(1);} * /    结构TM *地方;    焦炭toClient [50];    的printf(服务器:接受'%s'的\\ n,BUF);    time_t的CURTIME =时间(0);    本地=本地时间(安培; CURTIME);    如果(BUF [0] =='T'){        的printf(服务器:接收到的时间要求\\ n,S);        sprintf的(toClient,时间:%d个::%d个::%D,局域> tm_hour,局域> tm_min,局域> tm_sec); //赛格断层        的printf(已发送具有IP地址%s和端口号码%s \\ n个时间到客户端,S,服务);    }    否则,如果(BUF [0] =='D'){        的printf(服务器:接收日期的请求\\ n,S);        sprintf的(toClient,日期:%d个::%d个::%D,1900 +局域> tm_year,1 +局域> tm_mon,局域> tm_mday);        的printf(已发送具有IP地址%s和端口号码%s \\ n中的日期到客户端,S,服务);    }    其他{    }    如果((的numBytes =送(new_fd,toClient,sizeof的toClient,0))== -1){    PERROR(发送);    出口(1);}    关闭(new_fd);    打破; //临时}接近(的sockfd);返回0;}

解决方案

问题是在你的 inet_ntop 电话:

inet_ntop(对GT; ai_family,get_in_addr((结构sockaddr *)&P- GT; ai_addr)          主机,主机的sizeof);

在这里,你正在使用指针 P 呼叫后

freeaddrinfo(servinfo);

您需要复制该结构的sockaddr 和 socklen_t的你有的getaddrinfo 在某些变量或存储结构 addrinfo中的继续使用。否则会导致不确定的行为,就像你正在经历。请记住,Valgrind是你的朋友。

I'm trying to find a way to get my server to print its TCP Port Number and IP address but how I have it right now is producing the wrong IP, I am getting an output of 0.0.33.32. Any help is appreciated!

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <arpa/inet.h> #include <sys/wait.h> #include <signal.h> #include <time.h> #define PORT "21467" // the port users will be connecting to #define BACKLOG 10 // how many pending connections queue will hold void sigchld_handler(int s) { while(waitpid(-1, NULL, WNOHANG) > 0); } // get sockaddr, IPv4 or IPv6: void *get_in_addr(struct sockaddr *sa) { if (sa->sa_family == AF_INET) { return &(((struct sockaddr_in*)sa)->sin_addr); } return &(((struct sockaddr_in6*)sa)->sin6_addr); } int main(void) { int sockfd, new_fd; // listen on sock_fd, new connection on new_fd struct addrinfo hints, *servinfo, *p; struct sockaddr_storage their_addr; // connector's address information socklen_t sin_size; struct sigaction sa; int yes=1; char s[INET6_ADDRSTRLEN]; int rv; memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; // use my IP char hname[100]; gethostname(hname, sizeof hname); if ((rv = getaddrinfo(hname, PORT, &hints, &servinfo)) != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); return 1; } // loop through all the results and bind to the first we can for(p = servinfo; p != NULL; p = p->ai_next) { if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { perror("server: socket"); continue; } if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); } if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { close(sockfd); perror("server: bind"); continue; } break; } if (p == NULL) { fprintf(stderr, "server: failed to bind\n"); return 2; } freeaddrinfo(servinfo); // all done with this structure if (listen(sockfd, BACKLOG) == -1) { perror("listen"); exit(1); } sa.sa_handler = sigchld_handler; // reap all dead processes sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; if (sigaction(SIGCHLD, &sa, NULL) == -1) { perror("sigaction"); exit(1); } char host[100]; char service[20]; getnameinfo(p->ai_addr, p->ai_addrlen, host, sizeof host, service, sizeof service, 0); inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), host, sizeof host); printf("server: has TCP port number %s and IP address %s\n", service, host); printf("server: waiting for connections...\n"); int numbytes; char buf[100]; while(1) { // main accept() loop sin_size = sizeof their_addr; new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size); if (new_fd == -1) { perror("accept"); continue; } inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s); //getnameinfo(get_in_addr((struct sockaddr *)&their_addr), sizeof get_in_addr((struct sockaddr *)&their_addr), NULL, NULL, service, sizeof service, 0); if ((numbytes = recv(new_fd, buf, 100, 0)) == -1) perror("recv"); /* if ((numbytes = recv(sockfd, buf, 100, 0)) == -1) { perror("recv"); exit(1); }*/ struct tm* local; char toClient[50]; printf("server: received '%s'\n",buf); time_t curTime = time(0); local = localtime(&curTime); if(buf[0] == 't' ){ printf("server: received time request\n", s); sprintf(toClient, "Time: %d::%d::%d", local->tm_hour, local->tm_min, local->tm_sec); //Seg faulting printf("Sent the time to the client having IP address %s and port number %s\n", s, service); } else if(buf[0] == 'd'){ printf("server: received date request\n", s); sprintf(toClient, "Date: %d::%d::%d", 1900+local->tm_year, 1+local->tm_mon, local->tm_mday); printf("Sent the date to the client having IP address %s and port number %s\n", s, service); } else{ } if ((numbytes = send(new_fd, toClient, sizeof toClient, 0)) == -1) { perror("send"); exit(1); } close(new_fd); break; //Temporary } close(sockfd); return 0; }

解决方案

The problem is in your inet_ntop call:

inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), host, sizeof host);

In here you are using pointer p after calling

freeaddrinfo(servinfo);

You need to copy the struct sockaddr and socklen_t you got from getaddrinfo in some variables, or store the struct addrinfo for further use. Otherwise you will cause undefined behavior, like you are now experiencing. Remember, Valgrind is your friend.

更多推荐

需要帮忙用C TCP端口号和IP地址

本文发布于:2023-08-07 13:46:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1319379.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:端口号   地址   TCP   IP

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!