实际上,我的问题非常令人气愤.我先给你看一下代码.
/* ** listener.c -- a datagram sockets "server" demo */ //Original Code: Brian Hall (beej@beej.us) //Commented and modified by Vishal Kotcherlakota (PID A07124450) #include#include #include #include #include #include #include #include #include #include #define MYPORT "4960" // the port users will be connecting to #define YOURPORT "4961" #define MAXBUFLEN 10000 // get sockaddr, IPv4 or IPv6: void *get_in_addr(struct sockaddr *sa) { //If the socket address struct says it's an IPv4... if (sa->sa_family == AF_INET) { //...return the IPv4 variable. return &(((struct sockaddr_in*)sa)->sin_addr); } //otherwise, assume it's IPv6, and get the IPv6 variable return &(((struct sockaddr_in6*)sa)->sin6_addr); } int main(int argc, char *argv[]) { int sockfd, sockfdAck; //socket file descriptor (handle) struct addrinfo hints, *servinfo, *p, *q; int rv; int numbytes; unsigned int seqNum, stateNum=0, ackNum; struct sockaddr_storage their_addr; struct timeval recvTime, timeStamp, latency; char buf[MAXBUFLEN], junk[MAXBUFLEN]; size_t addr_len; char *ackBack; char s[INET6_ADDRSTRLEN]; if (argc != 2) { fprintf(stderr, "usage: \n"); exit(0); } memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4 hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_PASSIVE; // use my IP if ((rv = getaddrinfo(NULL, MYPORT, &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(q = servinfo; q != NULL; q = q->ai_next) { if ((sockfd = socket(q->ai_family, q->ai_socktype, q->ai_protocol)) == -1) { perror("listener: socket"); continue; } if (bind(sockfd, q->ai_addr, q->ai_addrlen) == -1) { close(sockfd); perror("listener: bind"); continue; } break; } if (q == NULL) { fprintf(stderr, "listener: failed to bind socket\n"); return 2; } freeaddrinfo(servinfo); memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4 hints.ai_socktype = SOCK_DGRAM; if ((rv = getaddrinfo(argv[1], BACKPORT, &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 ((sockfdAck = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { perror("listener: socket"); continue; } break; } if (p == NULL) { fprintf(stderr, "listener: failed to bind socket\n"); return 2; } freeaddrinfo(servinfo); printf("listener: waiting to recvfrom...\n"); while (1) { addr_len = sizeof their_addr; if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0, (struct sockaddr *)&their_addr, &addr_len)) == -1) { perror("recvfrom"); exit(1); } /*printf("listener: got packet from %s\n", inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s)); printf("listener: packet is %d bytes long\n", numbytes); */ buf[numbytes] = '\0'; sscanf(buf,"%u %s",&seqNum, junk); if (seqNum == stateNum + 1) { stateNum = seqNum; printf("Ok, state is now %u.\n", stateNum); } ackBack = malloc(20*sizeof(char)); sprintf(ackBack, "%u acknowledged\0", stateNum); numbytes = sendto(sockfdAck, ackBack, strlen(ackBack), 0, p->ai_addr, p->ai_addrlen); if (numbytes == -1); { perror("sendto"); exit(1); } free(ackBack); } return 0; }
请原谅邋code的代码; 我拼命想按时完成这项任务.目标是使用数据报套接字开发ARQ协议.这段代码应该可以工作,但是当我运行它时,我收到一个错误sendto: Success
,这意味着我的sendto()
调用失败了.我无法在任何地方找到这方面的文档,而且我变得非常绝望.
它与必须无关bind()
- 事实上看一下这个语法:
if (numbytes == -1) ; // semicolon ! { perror("sendto"); exit(1); }
你有一个没有身体的条件,然后是没有条件的身体,它总是执行(你可以观察到).
添加numbytes的printf,您将看到它设置正确,没有错误.
为了避免这种难以看到的错误,我通常会在条件之后立即放置开口支架 - 然后你会立即发现它.但当然这是公司/项目编码惯例的问题.