c-socket-programming:recvfrom
تابع ()recvfrom
این تابع برای خواندن از سوکت های SOCK_DGRAM استفاده می شود.
#include <sys/types.h> #include <sys/socket.h> ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
مثال برای خواندن درخواست های DNS از کلاینت dig و نمایش آنها
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <arpa/inet.h> #define PORT "53" int main() { int status, sockfd; struct addrinfo hints, *res, *rp; memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_PASSIVE; hints.ai_family = AF_INET; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = 0; status = getaddrinfo(NULL, PORT, &hints, &res); if (status != 0) { fprintf(stderr, "getaddrinfo() error: %s\n", gai_strerror(status)); exit(EXIT_FAILURE); } for (rp = res; rp != NULL; rp = rp->ai_next) { sockfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (sockfd == -1) { perror("socket() error "); continue; } status = bind(sockfd, rp->ai_addr, rp->ai_addrlen); if (status == -1) { perror("bind() error "); close(sockfd); continue; } break; } freeaddrinfo(res); if (rp == NULL) { fprintf(stderr, "Could not bind()\n"); exit(EXIT_FAILURE); } ssize_t readlen; char buf[BUFSIZ]; struct sockaddr_storage src_addr; socklen_t addrlen = sizeof(src_addr); readlen = recvfrom(sockfd, buf, BUFSIZ, 0, (struct sockaddr *)&src_addr, &addrlen); if (readlen == -1) { perror("recvfrom() error "); exit(EXIT_FAILURE); } char *ipver, ipstr[INET6_ADDRSTRLEN]; void *addr; if (src_addr.ss_family == AF_INET6) { ipver = "IPv6"; addr = &(((struct sockaddr_in6 *)&src_addr)->sin6_addr); } else { ipver = "IPv4"; addr = &(((struct sockaddr_in *)&src_addr)->sin_addr); } inet_ntop(src_addr.ss_family, addr, ipstr, INET6_ADDRSTRLEN); printf("Got an %s connection from %s\n", ipver, ipstr); unsigned char c; int i, j, k, space; printf("\nClient message: %d byte\n\n", readlen); for (i = 0; i < readlen; i+=16) { printf("\t0x%04x ", i); for (j = i; j < i+16 && j < readlen; j++) { c = (unsigned char)buf[j]; printf("%02X ", c); } if (j == i+16) space = 1; else space = 1 + (16*3) - (j-i)*3; for (k = 0; k < space; k++) printf(" "); for (j = i; j < i+16 && j < readlen; j++) { c = (unsigned char)buf[j]; if (c <= 32 || c >= 127) c = '.'; printf("%c", c); } printf("\n"); } printf("\n"); close(sockfd); return 0; }
کلاینت dig
$ dig @127.0.0.1 google.com ; <<>> DiG 9.16.27-Debian <<>> @127.0.0.1 google.com ; (1 server found) ;; global options: +cmd ;; connection timed out; no servers could be reached
خروجی سرور
Got an IPv4 connection from 127.0.0.1
Client message: 51 byte
0x0000 6C 29 01 20 00 01 00 00 00 00 00 01 06 67 6F 6F l)...........goo
0x0010 67 6C 65 03 63 6F 6D 00 00 01 00 01 00 00 29 10 gle.com.......).
0x0020 00 00 00 00 00 00 0C 00 0A 00 08 72 1C F7 76 B8 ...........r..v.
0x0030 B2 D5 BF ...
c-socket-programming/recvfrom.txt · آخرین ویرایش: 2024/06/18 01:01 توسط pejman
