LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1127|回复: 11

Debian下服务器端Sendto()函数的问题

[复制链接]
发表于 2006-8-22 00:40:00 | 显示全部楼层 |阅读模式
最近拜读了007xiong整理的《linux操作系统下c语言编程入门》,在Debian系统下试了里面的基于UDP协议的网络程序。具体代码如下:
/* 服务端程序 server.c */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <errno.h>
#define SERVER_PORT 8888
#define MAX_MSG_SIZE 1024
void udps_respon(int sockfd)
{
        struct sockaddr_in addr;
        int addrlen,n;
        char msg[MAX_MSG_SIZE];
        while(1)
        { /* 从网络上度,写到网络上面去 */
                n=recvfrom(sockfd,msg,MAX_MSG_SIZE,0,(struct sockaddr*)&addr,&addrlen);
                msg[n]=0;
                /* 显示服务端已经收到了信息 */
                fprintf(stdout,"I have received %s",msg);
                sendto(sockfd,msg,n,0,(struct sockaddr*)&addr,addrlen);
        }
}
int main(void)
{
        int sockfd;
        struct sockaddr_in addr;
        sockfd=socket(AF_INET,SOCK_DGRAM,0);
        if(sockfd<0)
        {
                fprintf(stderr,"Socket Error:%s\n",strerror(errno));
                exit(1);
        }
        bzero(&addr,sizeof(struct sockaddr_in));
        addr.sin_family=AF_INET;
        addr.sin_addr.s_addr=htonl(INADDR_ANY);
        addr.sin_port=htons(SERVER_PORT);
        if(bind(sockfd,(struct sockaddr *)&addr,sizeof(struct sockaddr_in))<0
          )
        {
                fprintf(stderr,"Bind Error:%s\n",strerror(errno));
                exit(1);
        }
        udps_respon(sockfd);
        close(sockfd);
}


/* 客户端程序 */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#define MAX_BUF_SIZE 1024
void udpc_requ(int sockfd,const struct sockaddr_in *addr,int len)
{
        char buffer[MAX_BUF_SIZE];
        int n;
        while(1)
        { /* 从键盘读入,写到服务端 */
                fgets(buffer,MAX_BUF_SIZE,stdin);
                sendto(sockfd,buffer,strlen(buffer),0,addr,len);
                bzero(buffer,MAX_BUF_SIZE);
                /* 从网络上读,写到屏幕上 */
                n=recvfrom(sockfd,buffer,MAX_BUF_SIZE,0,NULL,NULL);
                buffer[n]=0;
                fputs(buffer,stdout);
        }
}
int main(int argc,char **argv)
{
        int sockfd,port;
        struct sockaddr_in addr;
        if(argc!=3)
        {
                fprintf(stderr,"Usage:%s server_ip server_port\n",argv[0]);
                exit(1);
        }
        if((port=atoi(argv[2]))<0)
        {
                fprintf(stderr,"Usage:%s server_ip server_port\n",argv[0]);
                exit(1);
        }
        sockfd=socket(AF_INET,SOCK_DGRAM,0);
        if(sockfd<0)
        {
                fprintf(stderr,"Socket Error:%s\n",strerror(errno));
                exit(1);
        }
        /* 填充服务端的资料 */
        bzero(&addr,sizeof(struct sockaddr_in));
        addr.sin_family=AF_INET;
        addr.sin_port=htons(port);
        if(inet_aton(argv[1],&addr.sin_addr)<0)
        {
                fprintf(stderr,"Ip error:%s\n",strerror(errno));
                exit(1);
        }
        udpc_requ(sockfd,&addr,sizeof(struct sockaddr_in));
        close(sockfd);
}

编译完,在Redhat系统下,客户端和服务器端都可以正常发送、接收数据。在Debian系统下运行后,发现服务器端的recvfrom()函数可以正常接收数据,而sendto()函数切不能正常发送数据。不知道Debian系统是不是有什么漏洞问题,请知道如何解决的高手们不吝赐教,谢谢!
发表于 2006-8-22 10:01:48 | 显示全部楼层
man recvfrom 查fromlen
出问题的时候,不要轻易怀疑库和系统,呵呵
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-8-22 11:15:43 | 显示全部楼层
recvfrom的fromlen参数没问题吧,因为在别的系统下调试都能正常实现所要的功能,为何在Debian下就出问题了呢?

在Redhat下调试时,C/S收发都很正常。或者是Redhat当服务器端,debian当客户端也收发正常。只要让debian当服务端就出问题。服务端能收到信息,但客户端就收到不到信息,一直处于等待状态。
回复 支持 反对

使用道具 举报

发表于 2006-8-22 12:14:11 | 显示全部楼层
系统是否开了防火墙?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-8-22 15:30:21 | 显示全部楼层
没有啊,debian下的iptables的默认规则是空的,我没去配置它
回复 支持 反对

使用道具 举报

发表于 2006-8-23 00:26:03 | 显示全部楼层
Post by x11
出问题的时候,不要轻易怀疑库和系统,呵呵
这个俺是有体会的。
n=recvfrom(sockfd,msg,MAX_MSG_SIZE,0,(struct sockaddr*)&addr,&addrlen);
老大,最后一个[color="Red"]变量没有初始化!在其他版本上可以?俺试了,加上初始化是正常了,俺用Sid。
不过这个程序是不是旧了点,参数与现在的都不一致了。
编程也太不严谨了,返回值都不检查,只能是试验一下。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-8-24 23:40:35 | 显示全部楼层
不好意思,俺是新手。
俺用的是sarge。不够该程序在redhat9下运行得好好的,所以我觉得在debian是不是哪里有问题。后来初始化了addrlen,也检测了N的值,都没问题啊。可是在DEBIAN下还是不能正常收发信息,郁闷啊。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-8-24 23:44:25 | 显示全部楼层
更奇怪的是把客户端的程序中
sendto(sockfd,buffer,strlen(buffer),0,addr,len);
改成:sendto(sockfd,buffer,strlen(buffer),0,(struct sockaddr*)&addr,len);的话整个程序都不能收发信息了
回复 支持 反对

使用道具 举报

发表于 2006-8-25 10:12:09 | 显示全部楼层
Post by waq
这个俺是有体会的。
老大,最后一个[color="Red"]变量没有初始化!在其他版本上可以?俺试了,加上初始化是正常了,俺用Sid。
不过这个程序是不是旧了点,参数与现在的都不一致了。
编程也太不严谨了,返回值都不检查,只能是试验一下。


1. 怀疑系统有问题,意味着要付出太多的精力放在没人能确定的问题上,很痛苦的

2. 多检查返回值,我看了你很多地方打印了错误串,为什么不在sendto的地方打印呢
   一旦知道是哪里错了,很容易解决问题的

PS: 楼主的代码在我的REDHAT和Debian下问题都是一样的,waq说的就是问题所在了
回复 支持 反对

使用道具 举报

发表于 2006-8-25 22:55:45 | 显示全部楼层
Post by eagelangel
不好意思,俺是新手。
俺用的是sarge。不够该程序在redhat9下运行得好好的,所以我觉得在debian是不是哪里有问题。后来初始化了addrlen,也检测了N的值,都没问题啊。可是在DEBIAN下还是不能正常收发信息,郁闷啊。

俺用Sid,修改后的代码俺试过了,客户端发一串,马上收回同一串,服务器端显示收到这个串。没有任何问题啊?Sarge应该比Sid更可靠吧,看来你要从其他方面找原因了。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表