免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 5833 | 回复: 23

一个网络编程中send的菜鸟问题 [复制链接]

论坛徽章:
0
发表于 2006-12-26 16:14 |显示全部楼层
刚接触linux网络编程,碰到一些烦人的小问题,比如说写一个测试程序,写了一个客户端和服务器端的程序,实现功能很简单,客户端发送一个字符串给服务器断,服务器断将这个字符串处理一下然后返回给客户端,在我建立了连接之后在客户端用send()之后发现服务器断接收不到字符串,后来测试了半天我在send之后马上关掉连接的socket文件sockfd服务器端马上就收到了,我想问一下是不是每次send之后一定要关掉连接的sockfd才能再服务器端才能接收到客户端发送的字符串的??如果是这样我要再后面的程序中接收来自服务器端回送的字符串之后应该怎么办呢?总不能说我重新建立一个连接吧.......郁闷中.

论坛徽章:
0
发表于 2006-12-26 16:41 |显示全部楼层
send以后flush一下缓冲区
fflush()

论坛徽章:
0
发表于 2006-12-26 17:17 |显示全部楼层

回复 2楼 linyue 的帖子

兄弟,还是不行啊,谁和我说说,郁闷死了要

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
发表于 2006-12-26 17:18 |显示全部楼层
贴代码.

论坛徽章:
0
发表于 2006-12-26 17:50 |显示全部楼层

回复 4楼 mq110 的帖子

客户端:
#include<stdio.h>

#include<stdlib.h>

#include<unistd.h>

#include<sys/socket.h>

#include<arpa/inet.h>

#include<netinet/in.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<string.h>

#include<sys/time.h>



#define PORT 9877

#define BUFLEN 1024

#define MAXLEN 128

#define MAXSLEEP 128





int connect_retry(int sockfd,struct sockaddr *addr,socklen_t alen);

void printbuf(int sockfd);

void getbuf(int sockfd,char *buf);



int main(int argc,char *argv[])

{

        int sockfd;

        struct sockaddr_in serveraddr;

        int addrlen;

        char *str="hello";

        pid_t pid;

        /*char buf[BUFLEN];*/

        if(argc!=2)

        {

                printf("usage:clienttest ipaddress\n";

                exit(1);

        }

        if( (sockfd=socket(AF_INET,SOCK_STREAM,0))<0 )

        {

                perror("create socket error";

                exit(1);

        }

        bzero(&serveraddr,sizeof(serveraddr));

        serveraddr.sin_family=AF_INET;

        serveraddr.sin_port=htons(PORT);

        inet_pton(AF_INET,argv[1],&serveraddr.sin_addr);

        addrlen=sizeof(struct sockaddr);

        if( connect_retry(sockfd,(struct sockaddr *)&serveraddr,addrlen)<0 )

        {

                printf("connect to server error\n";

                exit(1);

        }

        if(send(sockfd,str,strlen(str),0)<0)

        {

                perror("send str to server error";

                exit(1);

        }
        fflush(sockfd);

        printbuf(sockfd);

        close(sockfd);

        exit(0);                       

}





/*

//connect_retry

*/

int connect_retry(int sockfd,struct sockaddr *addr,socklen_t alen)

{


        int nsec;

        for(nsec=1;nsec<MAXSLEEP;nsec<<=1)

        {

                if( connect(sockfd,addr,alen)==0 )

                        return 0;

                if(nsec<=MAXSLEEP/2)

                        sleep(nsec);

        }

        return (-1);

}





/*

//printbuf

*/

void printbuf(int sockfd)

{

        char buf[BUFLEN];

        fd_set rfd;

        struct timeval timeout;

        timeout.tv_sec=10;

        timeout.tv_usec=0;

        FD_ZERO(&rfd);

        FD_SET(sockfd,&rfd);

        switch(select(sockfd+1,&rfd,NULL,NULL,&timeout))

        {

                case -1:

                        perror("select error";

                        exit(1);

                case 0:

                        printf("receive data from server timeout";

                        break;

                default:

                        getbuf(sockfd,buf);

                        printf("Get string from server: ";

                        printf("%s",buf);

                        break;

        }

        printf("\n";

}





/*

//getbuf

*/

void getbuf(int sockfd,char *buf)

{

        char tempbuf[MAXLEN];

        int i,n,index;

        n=0;

        index=0;

        while( (n=recv(sockfd,tempbuf,MAXLEN,0))>0 )

        {

                for(i=0;i<n;i++)

                        buf[index++]=tempbuf[i];

        }

        buf[index]='\0';

        if(n<0)

        {

                perror("recv data from server error";

                exit(1);

        }

}

               


服务器端:
#include<stdio.h>

#include<stdlib.h>

#include<unistd.h>

#include<sys/socket.h>
#include<sys/wait.h>

#include<arpa/inet.h>

#include<netinet/in.h>

#include<string.h>



#define PORT 9877

#define BUFLEN 1024

#define MAXLEN 128

#define BACKLOG 10



void getbuf(char *buf,int sockfd);

void reversebuf(char *buf);



/*

//main

*/

int main(int argc,char *argv[])

{

        /*init serversockfd,clientsockfd;*/

        int listenfd,connectfd;

        int clientaddrlen;

        int status;

        struct sockaddr_in clientaddr,serveraddr;

        char buf[BUFLEN];

        char *welcome="Connect to server successful.Welcome!!!\n";

        pid_t pid;

        if( (listenfd=socket(AF_INET,SOCK_STREAM,0))<0 )

        {

                /*create socket if failure exit*/

                perror("create socket error!";

                exit(1);

        }

        /*init serveraddr*/

        bzero(&serveraddr,sizeof(serveraddr));

        serveraddr.sin_family=AF_INET;

        serveraddr.sin_port=htons(PORT);

        serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);

        /*bind port and serveraddr to listenfd*/

        if( bind(listenfd,(struct sockaddr *)&serveraddr,sizeof(struct sockaddr))<0 )

        {

                perror("bind port failure!");

                exit(1);

        }

        if( listen(listenfd,BACKLOG)<0 )

        {

                perror("listen error");

                exit(1);

        }

        for(;;)

        {

                clientaddrlen=sizeof(clientaddr);

                if( (connectfd=accept(listenfd,(struct sockaddr *)&clientaddr,&clientaddrlen))<0 )

                {

                        perror("accept from client failure!");

                        exit(1);

                }
                printf("Received client: %s request\n",inet_ntoa(clientaddr.sin_addr));

                if( (pid=fork())<0 )

                {

                        perror("fork error");

                        exit(1);

                }

                else if( pid==0 )

                {
                        getbuf(buf,connectfd);

                        printf("Get client string: %s\n",buf);
                        if( send(connectfd,welcome,strlen(welcome),0)<0 )

                        {

                                perror("send welcome failure");

                                exit(1);

                        }
                        reversebuf(buf);        /*reverse buf*/

                        if( send(connectfd,buf,strlen(buf),0)<0 )        /*send reversed string to client*/

                        {

                                perror("send reversed string error");

                                exit(1);

                        }
                        close(connectfd);
                        exit(0);

                }
                close(connectfd);

        }

        close(connectfd);

        close(listenfd);

        exit(0);

}





/*

//getbuf

*/

void getbuf(char *buf,int sockfd)

{

        char tempbuf[MAXLEN];

        int n;

        int i,index;

        index=0;

        n=0;

        while( (n=recv(sockfd,tempbuf,MAXLEN,0))>0 )

        {

                for(i=0;i<n;i++)

                buf[index++]=tempbuf[i];

        }

        buf[index]='\0';

        if(n<0)

        {

                perror("recv error");

                exit(1);

        }

}





/*

//reversebuf

*/

void reversebuf(char *buf)

{

        char c;

        int i,len;

        len=strlen(buf);

        int mid=(int)len/2;

        for(i=0;i<mid;i++)

        {

                c=buf[i];

                buf[i]=buf[len-1-i];

                buf[len-1-i]=c;

        }

}

论坛徽章:
0
发表于 2006-12-26 20:30 |显示全部楼层
我晕,你server的程序里那个getbuf函数里有个while循环不停recv,而你用的又是阻塞模式,所以你收到第一个字符串"hellp"以后,recv又阻塞在while那儿了,当然看上去就跟没受到东西一样了,其实已经收到了,这是程序设计的问题…

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
发表于 2006-12-26 20:36 |显示全部楼层
首先,我真的很不相信你编译的时候连个warning都可以。却对warning视而不见

论坛徽章:
0
发表于 2006-12-26 20:41 |显示全部楼层
原帖由 cjaizss 于 2006-12-26 20:36 发表
首先,我真的很不相信你编译的时候连个warning都可以。却对warning视而不见


其次在哪儿呢?- -。。。
他的问题跟那个warning一点关系也没有,那个warning是他用fflush的时候给错参数了,应该给个FILE,他给了个文件描述符。其实不用fflush..

论坛徽章:
0
发表于 2006-12-26 20:44 |显示全部楼层
原帖由 linyue 于 2006-12-26 20:41 发表


其次在哪儿呢?- -。。。
他的问题跟那个warning一点关系也没有,那个warning是他用fflush的时候给错参数了,应该给个FILE,他给了个文件描述符。其实不用fflush..


嗯。如果必须,可以用 fsync

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
发表于 2006-12-26 20:50 |显示全部楼层
原帖由 langue 于 2006-12-26 20:44 发表


嗯。如果必须,可以用 fsync

楼主程序的问题不是出在这里
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP