免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3595 | 回复: 13
打印 上一主题 下一主题

一个socket问题,请指教! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-12-09 21:30 |只看该作者 |倒序浏览
近日编写了一个server 和client的程序,
本意是双方建立连接以后在client端发送许一行数据,server端每收到一行后显示打印一行。
并用do……while循环控制不断发送。最后输入‘c’字符结束程序,server收到‘c’字符后结束程序。

可现在,在client端能发送很多行数据,可在server端要接收玩所有的数据后等client释放连接close(sockfd);以后再一起打印,然后进入下一个循环。
如果试着在client程序中把close(sockfd);放入循环的话,程序就会出错退出。

正在寻找方法……
现把程序附上,请高手指点迷津。

/*======================================           client.c         ===============================================*/

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netdb.h>
#define SERVPORT 3000
#define MAXDATASIZE 1024
main( int argc , char *argv[] )
{
   struct hostent *host;
   struct sockaddr_in serv_addr;
   int sockfd,sendbytes;
   int i;
   char bufdata[MAXDATASIZE];
   if( argc < 2)
   {
     fprintf(stderr, "Please enter the server's hostname!\n");
     exit(1);
   }

  *bufdata=='1';
  i=0;
  if( (host = gethostbyname(argv[1])) == NULL ){
       perror("gethostbyname");
       exit(1);
   }
  if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
       perror("socket");
       exit(1);
   }else{
   printf("socket success!,socket = %d\n",sockfd);
  }
   serv_addr.sin_family = AF_INET;
   serv_addr.sin_port = htons(SERVPORT);
   serv_addr.sin_addr = *( (struct in_addr *)host->h_addr );
   bzero(&(serv_addr.sin_zero), 8);
   if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) == -1 ){
       perror("connect");
       exit(1);
    }
  printf("connect success!\n");
  do
  {
  printf("\nPlease enter the command NO.%d:",i++);
  scanf("%s",bufdata);
  printf("\nThe %s must be sent.",bufdata);
  if(( sendbytes = send(sockfd, bufdata ,strlen(bufdata), 0)) == -1){
                perror("send");
                exit(1);
    }else{
        printf("\nThe command NO.%d have benn sent.",i-1);
        }
}while(*bufdata!='c');
  printf("\nSend over!Close socket\n");
  close(sockfd);
}



/*=====================================                  server.c                     =========================================*/

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#define SERVPORT 3000
#define BACKLOG 10
#define MAX_CONNECTED_NO 10
#define MAXDATASIZE 1024
int main()
{
   struct sockaddr_in  server_sockaddr,client_sockaddr;
   int sin_size,recvbytes;
   int sockfd,client_fd;
   int i;
   char bufdata[MAXDATASIZE];
    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
        perror("socket failed \n");
        exit(1);
   }
   printf("socket success!,sockfd = %d\n",sockfd);
   server_sockaddr.sin_family = AF_INET;
   server_sockaddr.sin_port = htons(SERVPORT);
   server_sockaddr.sin_addr.s_addr = INADDR_ANY;
   bzero(&(server_sockaddr.sin_zero), 8);
   if(bind(sockfd, (struct sockaddr *)&server_sockaddr, sizeof(struct sockaddr)) == -1 ){
       perror("bind failed!\n");
       exit(1);
          }
        printf("bind success!\n");
    if(listen(sockfd, BACKLOG) == -1){
           perror("listen failed!\n");
           exit(1);
         }
         printf("listening......\n");
        i=0;
        do
        {
         bufdata[0]='a';
        printf("1\n");
        client_fd = accept(sockfd, (struct sockaddr *)&client_sockaddr, &sin_size);
        printf("client_fd=%d\n",client_fd);
         if( client_fd == -1 )
        {
          perror("accept failed \n");
          exit(1);
       }else{
        printf("accept success\n");
        }
         printf("2\n");
        printf("connect from: %s,port: %d\n",inet_ntoa(client_sockaddr.sin_addr.s_addr),ntohs(client_sockaddr.sin_port));

        if(( recvbytes = recv(client_fd, bufdata, MAXDATASIZE, MSG_WAITALL)) == -1)
        {
           perror("recv failed!\n");
           exit(1);
        } else{
                printf("recv success\n");
        }
     printf("\nThe NO.%d bufdata is: ",i++) ;
     puts(bufdata);
     printf("\n Restart.\n");
     }while(bufdata[0]!='c');
    close(sockfd);
}


把源代码用附件附上,在redhat9编译通过,在高版本上也应该没有问题的。

[ 本帖最后由 hantor 于 2007-12-9 21:32 编辑 ]

client_server.rar

1.6 KB, 下载次数: 49

论坛徽章:
0
2 [报告]
发表于 2007-12-10 22:31 |只看该作者
没人回答,自己顶。
等待高手的出现!!!

论坛徽章:
0
3 [报告]
发表于 2007-12-11 16:19 |只看该作者
printf之后,刷新缓冲区

论坛徽章:
0
4 [报告]
发表于 2007-12-11 21:02 |只看该作者
zhuyingwei,能不能详细一点。

论坛徽章:
0
5 [报告]
发表于 2007-12-11 21:28 |只看该作者

回复 #1 hantor 的帖子

你的bufdata已经将多行程序接受结束,你要是打印单行可以在server端打印bufdata的时候做处理啊。
bufdata中换行符区分,打印单行

论坛徽章:
0
6 [报告]
发表于 2007-12-11 21:42 |只看该作者
问题并不是出在打印的时候,而是出在server.c中的:
recvbytes = recv(client_fd, bufdata, MAXDATASIZE, MSG_WAITALL)
只要client端不close(sockfd),它就把client多次send出来的数据一次接着一次得放到bufdata里面。
当client端close(sockfd)的时候,printf("\nThe NO.%d bufdata is: ",i++) ; puts(bufdata);语句才生效,也
就是把client多次send出来的数据一行打印完毕。

论坛徽章:
0
7 [报告]
发表于 2007-12-11 21:54 |只看该作者

回复 #6 hantor 的帖子

我知道你的意思。如果想得到一行一行的结果的话。你就可以在client端每一行输入有个结束标志,在server端打印时按照这个标志输出

论坛徽章:
0
8 [报告]
发表于 2007-12-11 22:15 |只看该作者

回CIT:

这样的一行一行显示对项目要求来说是没有意义的。
我要的是client每使用send语句发送一次,server就要recv接收一次并且打印出来。

论坛徽章:
0
9 [报告]
发表于 2007-12-12 01:02 |只看该作者
你不设置MSG_WAITALL不就行了

论坛徽章:
0
10 [报告]
发表于 2007-12-12 23:11 |只看该作者
设置成0也不行。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP