c中的简单客户端服务器

时间:2016-02-01 16:31:26

标签: c sockets

我无法理解代码无效的原因。 sendall和revcall取自beej指南。当我将数据从服务器发送到客户端时,它们没有输出。有人可以解释代码中的错误。它主要来自beej guide.Ot pipe中的一个问题,即当端口关闭时读取但是当端口关闭时我无法理解。

服务器代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>

#define MAX_SIZE 50

void error(const char *msg)
{
   perror(msg);
   exit(1);
}


/* sends all data - thanks to Beej's Guide to Network Programming */
int sendall(int s, char *buf, int *len)
{
   int total=0;
   int bytesleft=*len;
   int n=0;

  /* send all the data */
  while(total<*len)
  {

    /* send some data */
    n=send(s,buf+total,bytesleft,0);

   /* break on error */
   if(n==-1)
     break;

   /* apply bytes we sent */
   total+=n;
   bytesleft-=n;
  }

  /* return number of bytes actually send here */
  *len=total;

  /* return -1 on failure, 0 on success */
  return n==-1?-1:0;
}



int main(int argc, char *argv[])
{
    int sockfd, newsockfd, portno;
    socklen_t clilen;
    char buffer[256];
    struct sockaddr_in serv_addr, cli_addr;
    int n;

   if (argc < 2) 
   {
      fprintf(stderr,"ERROR, no port provided\n");
      exit(1);
   }

  sockfd = socket(AF_INET, SOCK_STREAM, 0);

  printf("sockfd : %d",sockfd);

  if (sockfd < 0) 
        error("ERROR opening socket");
  bzero((char *) &serv_addr, sizeof(serv_addr));
  portno = atoi(argv[1]);
  serv_addr.sin_family = AF_INET;
  serv_addr.sin_addr.s_addr = INADDR_ANY;
  serv_addr.sin_port = htons(portno);

  if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
      error("ERROR on binding");

  listen(sockfd,5);
  clilen = sizeof(cli_addr);
  newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);


  if (newsockfd < 0) 
        error("ERROR on accept");

  char msg[1024] = "hello";
  int len = sizeof(msg);
  int xx = sendall(sockfd,(char*)msg,&len);

   close(newsockfd);
   close(sockfd);
  return 0; 
}

客户端代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h> 
#include<errno.h>

void error(const char *msg)
{
   perror(msg);
   exit(0);
}

/* receives all data - modelled after sendall() */
int recvall(int s, char *buf, int *len, int timeout)
{
  int total=0;
  int bytesleft=*len;
  int n=0;
  time_t start_time;
  time_t current_time;

  /* clear the receive buffer */
  bzero(buf,*len);

  time(&start_time);

  /* receive all data */
  while(total<*len)
  {

      /* receive some data */
      n=recv(s,buf+total,bytesleft,0);

      /* no data has arrived yet (non-blocking socket) */
      if(n==-1 && errno==EAGAIN)
      {
         time(&current_time);

         if(current_time-start_time>timeout)
            break;
         sleep(1);
         continue;
      }

/* receive error or client disconnect */
  else if(n<=0)
      break;

  /* apply bytes we received */
    total+=n;
    bytesleft-=n;
  }

 /* return number of bytes actually received here */
 *len=total;

 /* return <=0 on failure, bytes received on success */
  return (n<=0)?n:total;
}

int main(int argc, char *argv[])
{
  int sockfd, portno, n;
  struct sockaddr_in serv_addr;
  struct hostent *server;

  char buffer[1024];

  if (argc < 3) 
  {
    fprintf(stderr,"usage %s hostname port\n", argv[0]);
     exit(0);
  }
  portno = atoi(argv[2]);

  sockfd = socket(AF_INET, SOCK_STREAM, 0);

   if (sockfd < 0) 
     error("ERROR opening socket");

  serv_addr.sin_family = AF_INET; 
  serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");; 
  serv_addr.sin_port = htons(portno);

  if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) 
    error("ERROR connecting");

   int m = 1024;
    n = recvall(sockfd, buffer,&m,10);
    if (n < 0) 
        error("ERROR reading from socket");


  printf("%s\n",buffer);

  close(sockfd);
  return 0;
}

1 个答案:

答案 0 :(得分:0)

'int xx = sendall(sockfd,(char*)msg,&len);'

&#39;的sockfd&#39;是服务器侦听套接字。你应该使用&#39; newsockfd&#39;来调用sendall(),这是由accept()调用返回的。