我将在 C 中进行套接字编程,但我有一个问题 - 我敢肯定 - 它来自我的困惑:如何使用getaddrinfo()设置服务器,以及如何从客户端获取它的地址?我正在使用UDP。
(我来自Beej 的教程,但我仍然不明白)
这是我的服务器的代码(我试图在mhgc.net和端口 3051 上运行它,虽然我还没有找到设置...主机名的方法?对不起,我很困惑):
int sockd;
/* Get my IP address */
struct addrinfo hints, * servinfo;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE; // use my own address
if( getaddrinfo(NULL, "3051", &hints, &servinfo) != 0 ) {
/* Yes, below is not... 'pretty code'; this is just an attempt */
errorf("Failed to get server address: %s", gai_strerror( getaddrinfo(NULL, "3051", &hints, &servinfo) ));
exit(EXIT_FAILURE);
return 1;
}
struct addrinfo * p = NULL;
for(p = servinfo; p != NULL; p = p->ai_next) {
if( (sockd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1 ) {
perror("Cannot open socket");
continue;
}
if(bind(sockd, p->ai_addr, p->ai_addrlen) == -1) {
close(sockd);
perror("Cannot bind to port");
continue;
}
break;
}
if(p == NULL) {
error("listener: failed to bind socket");
exit(EXIT_FAILURE);
return 0;
}
freeaddrinfo(servinfo);
struct sockaddr_storage clientinfo;
socklen_t clientinfo_len = sizeof(clientinfo);
char buffer[15];
memset(buffer, 0, sizeof(buffer));
if( recvfrom(sockd, buffer, sizeof(buffer), 0, (struct sockaddr *)&clientinfo, &clientinfo_len) == -1 ) {
perror("Error receiving packet");
exit(EXIT_FAILURE);
return 0;
}
char s[INET6_ADDRSTRLEN];
printf("listener: got packet from %s\n", inet_ntop(clientinfo.ss_family, get_in_addr((struct sockaddr *)&clientinfo), s, sizeof(s)));
printf("listener: packet contains \"%s\"\n", buffer);
/* Close the socket descriptor */
close(sockd);
/* And now, exit, or whatever I need ... ... ... */
对于我的客户:
int sockd;
struct addrinfo hints, * servinfo;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
//hints.ai_flags = AI_CANONNAME;
if( getaddrinfo(MKS_HOSTNAME, "www", &hints, &servinfo) != 0 ) {
errorf("Failed to get server address: %s", gai_strerror( getaddrinfo(NULL, "3051", &hints, &servinfo) ));
return 1;
}
struct addrinfo * p = NULL;
for(p = servinfo; p != NULL; p = p->ai_next) {
if((sockd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
perror("Cannot open socket");
continue;
}
break;
}
if(p == NULL) {
error("talker: failed to bind socket");
return 2;
}
if( sendto(sockd, "this-is-a-test", strlen("this-is-a-test")+1, 0, p->ai_addr, p->ai_addrlen) == -1 ) {
perror("Error sending packet");
return 1;
}
freeaddrinfo(servinfo);
close(sockd);
error和errorf是帮助我调试应用程序的宏。不要担心他们。
另一个提示,如果您允许我的话:Beej 教程中的talker.c 使用主机名来“查找”服务器。我下载了 listener.c 和talker.c,编译了它(make listener && maketalker)但是,我不知道要传递什么作为talker 参数。侦听器的主机名是什么?我怎样才能找到它?再次抱歉。我真的很困惑:S
使用 gcc 编译器 v4.4.5 处理 Debian GNU/Linux “挤压”