基础的套接字编程,关于bind使用出错

yuanhaitaozz 2015-03-07 04:20:43
本人最近在学习 APUE, 一个问题解决不了,网上搜索也搜不到,所以到这里来提问。

这是书第十六章到关于服务器和客户端编程到基础示例,但是我在自己到系统上实践的时候却出现了问题。

代码如下:
#include <stdio.h>
#include <arpa/inet.h>
#include <syslog.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

#define BUFLEN 128
#define QLEN 10

#ifndef HOST_NAME_MAX
#define HOST_NAME_MAX 128
#endif

int initserver(int ,struct sockaddr * ,socklen_t ,int );
void server(int sockfd);
void set_cloexec(int);


int main(int ac,char *av[])
{
struct addrinfo hint, *ailist, *aip;
int err, sockfd, n;
char *host;
struct sockaddr_in *sinp;
const char *addr;
char abuf[INET_ADDRSTRLEN];

if(ac != 1)
{
fprintf(stderr,"ruptimed\n");
exit(1);
}

if((n=sysconf(_SC_HOST_NAME_MAX)) < 0)
n = HOST_NAME_MAX;

if((host=malloc(n)) == NULL)
{
perror("malloc");
exit(1);
}

if(gethostname(host,n) < 0)
{
perror("gethostname");
exit(1);
}

//daemonzie("ruptimed");

memset(&hint,0,sizeof(hint));
hint.ai_flags = AI_PASSIVE;
hint.ai_socktype = SOCK_STREAM;
hint.ai_canonname = NULL;
hint.ai_addr = NULL;
hint.ai_next = NULL;

if((err=getaddrinfo(host,"ruptime",&hint,&ailist)) != 0)
{
//syslog(LOG_ERR,"ruptime: getaddrinfo error: %s",gai_strerror(err));
fprintf(stderr,"getaddrinfo : %s\n",gai_strerror(err));
exit(1);
}

for(aip=ailist; aip!=NULL; aip=aip->ai_next)
{
if((sockfd=initserver(SOCK_STREAM,aip->ai_addr,aip->ai_addrlen,QLEN)) >= 0)
{
server(sockfd);
exit(0);
}
}
exit(1);
}

int initserver(int type, struct sockaddr *addr,socklen_t alen,int qlen)
{
int fd;
int err;

if((fd=socket(addr->sa_family,type,0)) < 0)
return -1;

if(bind(fd,addr,alen) < 0)
{
perror("bind");
close(fd);
return -1;
}

if(type==SOCK_STREAM || type==SOCK_SEQPACKET)
{
if(listen(fd,qlen) < 0)
{
close(fd);
return -1;
}
}

return fd;
}

void server(int sockfd)
{
int clfd;
FILE *fp;
char buf[BUFLEN];

set_cloexec(sockfd);
for(;;)
{
if((clfd=accept(sockfd,NULL,NULL)) < 0)
{
syslog(LOG_ERR,"ruptimed: accept error : %s",strerror(errno));
exit(1);
}
set_cloexec(clfd);
if((fp=popen("/usr/bin/uptime","r")) == NULL)
{
sprintf(buf,"error: %s\n",strerror(errno));
send(clfd,buf,strlen(buf),0);
}
else
{
while(fgets(buf,BUFLEN,fp) != NULL)
send(clfd,buf,strlen(buf),0);
pclose(fp);
}
close(clfd);
}
}

void set_cloexec(int sockfd)
{
int val;
val = fcntl(sockfd,F_GETFD);
val |= FD_CLOEXEC;
fcntl(sockfd,F_SETFD,val);
}


运行后一直出错:

bind: Cannot assign requested address


在/etc/services 中我添加了
ruptime 13000/tcp
(并没有与任何其他冲突)

上网查了也全是因为频繁访问导致这样的错误,而我这里刚运行这个程序就直接跳出这个错误
还希望各位帮助
...全文
189 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
yuanhaitaozz 2015-03-07
  • 打赏
  • 举报
回复
引用 5 楼 lee244868149 的回复:
确定你的系统中有打开ruptime这个进程吗 看一下/etc/services 下有没有ruptime程序注册的端口 netstat -tunlp |grep ruptime
...我的目的就是想要开启这个 ruptime这个服务进程, /etc/services 里也包含了这个服务与它对应的端口...
羽飞 2015-03-07
  • 打赏
  • 举报
回复
引用 6 楼 u012062760 的回复:
[quote=引用 4 楼 hnwyllmm 的回复:] 这个错误应该是IP地址格式或者设置错误,或者端口在合法范围内 看看端口是不是合法的,有没有做htons转换 试试简单的127.0.0.1 这种会不会有问题
恩 差不多就是格式上的错误我觉得。 我也查了许多相关的程序,发现在其他程序 设置地址+端口 这部分有许多不同。 有的程序使用 struct sockaddr_in 结构体,最后转化为 sockaddr 通过使用 htnol 和 htnos函数配置地址和端口(试了下可以执行) 还有的通过 gethostname + gethostbyname 来配置地址(试了下还是有bind错误) 我这里使用getaddrinfo,根据书上好像也没有也用到其他直接就是 struct sockaddr 结构体了,我想问一下,这些方式之间是什么关系呢? 我是新手,对这里感到挺迷惑的,不好意思 [/quote] 具体要看接口的说明了,我也没有看过,不好意思,我也不能确定这个接口是否对数据做过转换
yuanhaitaozz 2015-03-07
  • 打赏
  • 举报
回复
引用 4 楼 hnwyllmm 的回复:
这个错误应该是IP地址格式或者设置错误,或者端口在合法范围内 看看端口是不是合法的,有没有做htons转换 试试简单的127.0.0.1 这种会不会有问题
恩 差不多就是格式上的错误我觉得。 我也查了许多相关的程序,发现在其他程序 设置地址+端口 这部分有许多不同。 有的程序使用 struct sockaddr_in 结构体,最后转化为 sockaddr 通过使用 htnol 和 htnos函数配置地址和端口(试了下可以执行) 还有的通过 gethostname + gethostbyname 来配置地址(试了下还是有bind错误) 我这里使用getaddrinfo,根据书上好像也没有也用到其他直接就是 struct sockaddr 结构体了,我想问一下,这些方式之间是什么关系呢? 我是新手,对这里感到挺迷惑的,不好意思
奔跑的路 2015-03-07
  • 打赏
  • 举报
回复
确定你的系统中有打开ruptime这个进程吗 看一下/etc/services 下有没有ruptime程序注册的端口 netstat -tunlp |grep ruptime
羽飞 2015-03-07
  • 打赏
  • 举报
回复
这个错误应该是IP地址格式或者设置错误,或者端口在合法范围内 看看端口是不是合法的,有没有做htons转换 试试简单的127.0.0.1 这种会不会有问题
yuanhaitaozz 2015-03-07
  • 打赏
  • 举报
回复
引用 2 楼 baidu_24256693 的回复:
用lsof -i查看一下是不是你上一次运行的这个服务器程序还在,如过在用kill命令杀掉就行了
恩 我试了一下 可是并没有找到还在运行到相应进程
  • 打赏
  • 举报
回复
用lsof -i查看一下是不是你上一次运行的这个服务器程序还在,如过在用kill命令杀掉就行了
yuanhaitaozz 2015-03-07
  • 打赏
  • 举报
回复
本人还查看了得到的 addrinfo 结构体的内容如下:

$ ./SR1 
  family inet type stream protocol tcp
address 183.207.232.253 port 13000
bind: Cannot assign requested address

23,188

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧