首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

unix中简略的C/S文件通信(二)

2013-01-09 
unix中简单的C/S文件通信(二)我把unix中简单的C/S文件通信中的代码改进了下,服务器端给客户端发完文件,

unix中简单的C/S文件通信(二)
    我把"unix中简单的C/S文件通信"中的代码改进了下,服务器端给客户端发完文件,即客户端接收完文件后再给服务器端发文件,但程序似乎卡在了客户端发送文件那儿,求各位高手给看看,能给一些改进的提示也好,谢谢各位高手了,改进后原代码如下:
    newserver:
 #include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>



#define TRUE 1 /////////////
#define DataNum 126 //////////// 有用的126字节
#define BUFSIZE 128 ///////////// 每次发送128字节
#define PERM0644  /* 创建文件的默认属性*/
/*发的时候是128,*/
main ()
{
    int sock,length,clilen;
    struct sockaddr_in server,client;
    int msgsock;
    char newbuf[BUFSIZE];
    int newoutfile;
    ssize_t newnread;
    int j=0;
    int newrealn;
    char newcharnum;

    /******************************建立Socket连接*********************************/
    sock=socket(AF_INET,SOCK_STREAM,0); //申请socket资源   
    if (sock<0)
    {
        perror("opening stream socket");
        exit(1);
    }

    server.sin_family=AF_INET;
    server.sin_addr.s_addr=INADDR_ANY; /*必然的,这里指的是Internet协议*/
    server.sin_port=0;/*这里,是让系统自动分配一个端口号,在1024到5000之间65535个端口 ,端口设为0,系统自动分配 */  
    if (bind(sock,(struct sockaddr *)&server,sizeof server)<0) /*将IP地址和端口号绑到sock上 */
    {
        perror("binding stream socket");
        exit(1);
    }

    length=sizeof server;
    if (getsockname(sock,(struct sockaddr *)&server,&length)<0) /*获得指定socket的本地地址,成功返回0,错误返回-1*/
    {
        perror("getting socket name");
        exit(1);
    }
    printf("Socket port # %d\n",ntohs(server.sin_port)); /* 打印出系统分的端口号,给client用*/

    listen(sock,5); /*5个连接请求排队等待,一般5个 Pause Here 等待client连接*/

    /****************现在是等待客户来连接,如果来客户了,那就建好了socket,就可以当文件使用**********/
    clilen=sizeof client;   
    msgsock=accept(sock,(struct sockaddr *)&client,(int *) &clilen);/*创建一个新的与sock相同的socket并返回其值*/
    if (msgsock==-1) /*非并发处理,反复型*/
       perror("accept");
    else  
    { /**********这里开始进行文件处理,一直到最后************/
       int infile;
       ssize_t nread;
       char buf[BUFSIZE];                        // 发送/接收缓冲区


       int rval;
       int i = 0;                                /*计数器: 数据块编号*/

       if((infile=open("send.txt",O_RDONLY))==-1) //只读方式打开test.txt ,iffile文件指针
       {
          printf("send.txt NOT Found, or program stopped!\n");
          exit(1);
       }

       memset(buf,0,sizeof buf);/*缓冲区清零*/
       while((nread = read(infile,buf,DataNum)) > 0) /*将文件读到缓冲区, 每次读126字节 */
       {
           //printf("从文件中读了大小为 %d 的数据\n",nread);
           buf[DataNum]=nread;                    /* 把实际信息多少的数字放在发送缓冲区的最后第二字节*/
           i++;
           buf[DataNum+1] = (i%10)+48;           
           if(write(msgsock,buf,BUFSIZE) == -1)/*将缓冲区的内容写到msgsock*/
              printf("Error Writing sock\n");
           else
             printf("Sending the %d th pack to sock, size: %d \n",i,nread);

           memset(buf,0,sizeof buf);            /*缓冲区清零*/

           if((rval = read(msgsock,buf,BUFSIZE)) < 0) /*从sock读对方收到信息后的应答 */
              printf("Error Reading sock\n");
           else
              printf("The other side receives the pack numbered: %s \n\n", buf);
       }
       close(infile);
       printf("...Completing Reading the file test.txt\n");
            
    } 
 /*Newly Added Codes: The followed! */ 

   if((newoutfile=open("test3.txt",O_WRONLY|O_CREAT|O_TRUNC,PERM))==-1)           //创建文件  
   {
    printf("Error Create File\n");
    exit(1);
   }
   
   //memset(newbuf,0,sizeof newbuf);/*缓冲区清零*/
   while((newnread=read(sock,newbuf,BUFSIZE))>0)                                         /*从sock读取传来的文件内容到缓冲区*/


   { 
   printf("Reading the %dth pack from the sock,size is: %d,",++j,newnread);
   newrealn=newbuf[BUFSIZE-2];/*查一下有效内容长度*/
    
   printf("Valid length %d , numbered: %c\n\n",newrealn,newbuf[BUFSIZE-1]);
    if(newrealn==0)/*如果为0表示那边文件发完了,停止循环*/
    {
        printf(".....completing the file retrieval\n\n");
        break;
    }
  if(write(newoutfile,newbuf,newrealn)<newrealn)                                            /*将缓冲区的内容写到文件里*/
    printf("Error Writing in File\n");
     newcharnum=newbuf[BUFSIZE-1]; 
   memset(newbuf,0,sizeof newbuf);/*缓冲区清零*/

   newbuf[0]=newcharnum;/*准备告诉对方收到了第几块i+48是i的ASCII值*/
   write(sock,newbuf,BUFSIZE);/*把收到信息发回去*/
   }
   close(newoutfile);
   close(sock);
   exit(0);
}

    newclient:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

#define TRUE 1
#define BUFSIZE128
#define DataNum126 
#define PERM0644 /* 创建文件的默认属性*/

main(argc,argv)
int argc;
char *argv[];
{
  int sock,msgsock;
  struct sockaddr_in server,newserver;
  struct hostent *hp,*gethostbyname();
  
  int outfile,newinfile;
  ssize_t nread,newnread;
  char buf[BUFSIZE],newbuf[BUFSIZE];
  int rval,newrval;
  int realn;
  int clilen;
  int length;
  int i=0,j=0;/*小计数器*/
  char charnum;

  /***************************建立Socket连接*************************** ****/ 
  sock=socket(AF_INET,SOCK_STREAM,0); /* 申请一个套节字,AF_INET,SOCK_STREAM是指TCP协议*/
  if (sock<0)
  {
perror("opening stream socket");
exit(1);
  }

  server.sin_family=AF_INET;  /*必然的,这里指的是Internet协议*/
  hp=gethostbyname(argv[1]);  /*根据主机名查地址,返回指针指向hostent结构*/
  if (hp==0) /*当没有此主机名时*/
  {
fprintf(stderr,"%s:unknown host\n",argv[1]);
exit(2);
  }

  memcpy((char *)&server.sin_addr,(char *)hp->h_addr,hp->h_length); /*拷贝Internet地址*/
  server.sin_port=htons(atoi(argv[2]));  /*argv[2]是端口号,2000-5000都可以,这里,要看server的输出了*/

  if (connect(sock,(struct sockaddr *)&server,sizeof server)<0) /*根据server地址连接sock,建立一条真实的连接*/
  {
perror("connecting stream socket");
exit(1);
  }

/*************************上面建好了Socket连接,下面就是怎么用sock了,和对待文件一样***********/
 
 if((outfile=open("test2.txt",O_WRONLY|O_CREAT|O_TRUNC,PERM))==-1)           //创建文件  


 {
 printf("创建文件出错\n");
 exit(1);
 }
 
 memset(buf,0,sizeof buf);/*缓冲区清零*/
 while((nread=read(sock,buf,BUFSIZE))>0)                                         /*从sock读取传来的文件内容到缓冲区*/
 { 
 printf("Reading the %dth pack from the sock,size is: %d,",++i,nread);
 realn=buf[BUFSIZE-2];/*查一下有效内容长度*/
    
 printf("Valid length %d , numbered: %c\n\n",realn,buf[BUFSIZE-1]);
 if(write(outfile,buf,realn)<realn)                                            /*将缓冲区的内容写到文件里*/
 printf("Error Writing in File\n");
    charnum=buf[BUFSIZE-1]; 
 memset(buf,0,sizeof buf);/*缓冲区清零*/

 buf[0]=charnum;/*准备告诉对方收到了第几块i+48是i的ASCII值*/
 write(sock,buf,BUFSIZE);/*把收到信息发回去*/
  if(realn<126)/*如果为0表示那边文件发完了,停止循环*/
    {
        printf(".....completing the file retrieval\n\n");
        break;
    }
 }
 close(outfile);
  /*Newly Added Codes: The followed! */
  // clilen=sizeof newserver;
 //msgsock=accept(sock,(struct sockaddr *)&newserver,(int *)&clilen);/* 创建一个新的与sock相同的socket并返回其值*/
// if (msgsock==-1)       /*非并发处理,反复型*/
// perror("accept");
 if((newinfile=open("newtest.txt",O_RDONLY))==-1)             //只读方式打开newtest.txt  ,newinfile文件指针
 {
printf("newtest.txt NOT Found, or program stopped!\n");
exit(1);
}
 
 memset(newbuf,0,sizeof newbuf);/*缓冲区清零*/
 while((newnread=read(newinfile,newbuf,DataNum))>0) /*将文件读到缓冲区每次读126字节   */
 {
 printf("Reading data size of %d from the file\n",newnread);
 newbuf[DataNum]=newnread; /*把实际信息多少的数字放在发的数据后*/
j++;
newbuf[DataNum+1]=(j%10)+48;/*j+48是j的ASCII值*/
 if(write(sock,newbuf,BUFSIZE)<=newnread)                 /*将缓冲区的内容写到sock*/ 
printf("Error Writing sock\n");
else
 printf("Sending the %d th pack to sock, size: %d\n",j,newnread);
 
 memset(newbuf,0,sizeof newbuf);/*缓冲区清零*/
 
 if(newrval=read(sock,newbuf,BUFSIZE)<0)                    /*从sock读对方收到信息后的应答         */   
printf("Error Reading sock\n");
 else
 printf("The other side receives the pack numbered: %s \n\n",newbuf);
 }/*while*/
close(newinfile);
    printf("...Completing Reading the file test.txt\n");
close(sock);/*关闭临时套节字,内核试图发送已在队列的所有数据*/ 
 exit(0);


}
等待回复中......
[解决办法]
一定要学会把代码放在form里啊,一定要多自己调试调试,打点信息看看找找错误原因.
[解决办法]
你实在是太不仔细了。服务端write时的sock写错了,应该是msgsock,而不是sock。

修改后的代码:
server.c


.................
..................
if((newoutfile=open("test3.txt",O_WRONLY
[解决办法]
O_CREAT
[解决办法]
O_TRUNC,PERM))==-1) //创建文件   
{
printf("Error Create File\n");
exit(1);
}
printf("open test3.txt successful\n");
//memset(newbuf,0,sizeof newbuf);/*缓冲区清零*/
//while((newnread=read(sock,newbuf,BUFSIZE)) > 0) /*从sock读取传来的文件内容到缓冲区*/
while((newnread=read(msgsock,newbuf,BUFSIZE)) > 0) /*从sock读取传来的文件内容到缓冲区*/

printf("Reading the %dth pack from the sock,size is: %d,",++j,newnread);
newrealn=newbuf[BUFSIZE-2];/*查一下有效内容长度*/

printf("Valid length %d , numbered: %c\n\n",newrealn,newbuf[BUFSIZE-1]);
if(newrealn==0)/*如果为0表示那边文件发完了,停止循环*/
{
printf(".....completing the file retrieval[test3.txt]\n\n");
break;
}
if(write(newoutfile,newbuf,newrealn)<newrealn) /*将缓冲区的内容写到文件里*/
printf("Error Writing in File\n");
newcharnum=newbuf[BUFSIZE-1];  
memset(newbuf,0,sizeof newbuf);/*缓冲区清零*/

newbuf[0]=newcharnum;/*准备告诉对方收到了第几块i+48是i的ASCII值*/
write(msgsock,newbuf,BUFSIZE);/*把收到信息发回去*/
}
close(newoutfile);
close(sock);
exit(0);
....................

热点排行