BSD C Bind() 到 UDP 挂起的套接字
每个人。我正在做关于使用 UDP 构建 whois 服务的硬件。但是,当我执行代码时遇到问题。
这是我的代码:
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <pwd.h>
#include <arpa/inet.h>
#include <string.h>
/*
* Program: whoisserver
*
* Purpose: UNIX application program act as a server for the "whois"
* service on the local machine.
*
* Usage: whois hostname username
*/
#define MSG_LEN 1024
void whois(int sock);
int main(int argc,char *argv[]){
int s; /* Socket descriptors */
struct sockaddr_in local_addr;
struct hostent *hp;
char *myname;
myname = argv[0];// copy program name to name
printf("This is program: %s \n", myname);
/*
* Create a socket
* Address Family (AF_INET)
* UDP (SOCK_DGRAM)
*/
printf("-Allocating socket for incomming connections...\n");
if((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
perror("socket");
exit(1);
}
/*
Set Up local Address
address_family (AF_INET)
IP address (INADDR_ANY) ?
port number (use 6087 by default)
*/
local_addr.sin_port = 54020;
local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
local_addr.sin_family = AF_INET;
/*
Bind the socket to the service port
*/
printf("-Binding Service to Socket...\n");
int n = bind(s, (struct sockaddr *)&local_addr, sizeof local_addr);
if(n <0){
perror("bind");
printf("Problem in binding\n");
exit(1);
}
printf("-Waiting for incomming connection...");
whois(s);// Call whois
return(0);
}
/*
whois function
param: int s
Socket Descriptor
*/
void whois(int sock){
int len, t;
char bufin[MSG_LEN];
struct sockaddr_in remote_addr;
// Get the size of remote address
len = sizeof(remote_addr);
// Infinity loop
while(1){
struct passwd *p;
// recvfrom while waiting for new customers
if((t = recvfrom(sock, bufin, MSG_LEN, 0,
(struct sockaddr *) &remote_addr, &len))<0){
perror("recvfrom");
exit(0);
}
bufin[t] = '\0'; // end of string
if((p = getpwnam(bufin)) == NULL)
strcpy(bufin, "-- This is the result from Gang's server ---\nUser not found\n");
else{
/*Find passwd in pwd.h file. Here is the structure:
struct passwd {
char *pw_name;
char *pw_passwd;
uid_t pw_uid;
gid_t pw_gid;
char *pw_age;
char *pw_comment;
char *pw_gecos;
char *pw_dir;
char *pw_shell;
};
*/
// Print out all the field
sprintf(bufin, "-- This is the result from Gang's server ---\nUsername: %s\nPassword: %s\nAge: %s\nUID: %d\nGID: %d\nGECOS: %s\nDIR: %s\nSHELL: %s\nComment: %s\n",
p->pw_name,
p->pw_passwd,
p->pw_age,
p->pw_uid,
p->pw_gid,
p->pw_gecos,
p->pw_dir,
p->pw_shell,
p->pw_comment
);
}
sendto(sock, bufin, strlen(bufin), 0, (struct sockaddr *)&remote_addr, len);
}
}
程序在套接字的绑定地址处停止。这是输出:
{506}paradox:client_server$ a.out
This is program: a.out
-Allocating socket for incomming connections...
-Binding Service to Socket...
^Z
[1]+ Stopped a.out
我不知道原因是什么。顺便说一下,我使用的是 gcc 3.4.3。我也在 Mac 和 Ubuntu 上尝试过。相同的结果。
everyone. I was doing my hw about use UDP to build a whois service. Howver I encounter a problem when I execute my code.
Here is my code:
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <pwd.h>
#include <arpa/inet.h>
#include <string.h>
/*
* Program: whoisserver
*
* Purpose: UNIX application program act as a server for the "whois"
* service on the local machine.
*
* Usage: whois hostname username
*/
#define MSG_LEN 1024
void whois(int sock);
int main(int argc,char *argv[]){
int s; /* Socket descriptors */
struct sockaddr_in local_addr;
struct hostent *hp;
char *myname;
myname = argv[0];// copy program name to name
printf("This is program: %s \n", myname);
/*
* Create a socket
* Address Family (AF_INET)
* UDP (SOCK_DGRAM)
*/
printf("-Allocating socket for incomming connections...\n");
if((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
perror("socket");
exit(1);
}
/*
Set Up local Address
address_family (AF_INET)
IP address (INADDR_ANY) ?
port number (use 6087 by default)
*/
local_addr.sin_port = 54020;
local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
local_addr.sin_family = AF_INET;
/*
Bind the socket to the service port
*/
printf("-Binding Service to Socket...\n");
int n = bind(s, (struct sockaddr *)&local_addr, sizeof local_addr);
if(n <0){
perror("bind");
printf("Problem in binding\n");
exit(1);
}
printf("-Waiting for incomming connection...");
whois(s);// Call whois
return(0);
}
/*
whois function
param: int s
Socket Descriptor
*/
void whois(int sock){
int len, t;
char bufin[MSG_LEN];
struct sockaddr_in remote_addr;
// Get the size of remote address
len = sizeof(remote_addr);
// Infinity loop
while(1){
struct passwd *p;
// recvfrom while waiting for new customers
if((t = recvfrom(sock, bufin, MSG_LEN, 0,
(struct sockaddr *) &remote_addr, &len))<0){
perror("recvfrom");
exit(0);
}
bufin[t] = '\0'; // end of string
if((p = getpwnam(bufin)) == NULL)
strcpy(bufin, "-- This is the result from Gang's server ---\nUser not found\n");
else{
/*Find passwd in pwd.h file. Here is the structure:
struct passwd {
char *pw_name;
char *pw_passwd;
uid_t pw_uid;
gid_t pw_gid;
char *pw_age;
char *pw_comment;
char *pw_gecos;
char *pw_dir;
char *pw_shell;
};
*/
// Print out all the field
sprintf(bufin, "-- This is the result from Gang's server ---\nUsername: %s\nPassword: %s\nAge: %s\nUID: %d\nGID: %d\nGECOS: %s\nDIR: %s\nSHELL: %s\nComment: %s\n",
p->pw_name,
p->pw_passwd,
p->pw_age,
p->pw_uid,
p->pw_gid,
p->pw_gecos,
p->pw_dir,
p->pw_shell,
p->pw_comment
);
}
sendto(sock, bufin, strlen(bufin), 0, (struct sockaddr *)&remote_addr, len);
}
}
The program stops at bind address to socket. Here is the output:
{506}paradox:client_server$ a.out
This is program: a.out
-Allocating socket for incomming connections...
-Binding Service to Socket...
^Z
[1]+ Stopped a.out
I can't figure out what's the reason. By the way, I am using gcc 3.4.3. And I also tried it in Mac and Ubuntu. Same result.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
它似乎停止的原因是因为默认情况下标准输出是行缓冲的,并且此消息末尾没有换行符:
添加
\n
到该消息的末尾,您可能会发现它在recvfrom()
调用处阻塞。The reason it appears to stop is because standard output is line-buffered by default, and you don't have a newline at the end of this message:
Add a
\n
to the end of that message and you will likely find that it is blocking at therecvfrom()
call.有几件事您应该更改:
There's a couple things you should change:
memset(&local_addr, 0, sizeof(local_addr));
That way you're sure that everything is appropriately initialized.local_addr.sin_port = htons(54020);
The port also must be in network order.