-1

私のクライアント/サーバー アプリケーションで奇妙なことが起こっています。これらの単純な fork クライアント/サーバーを見てください: CLIENT:

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/wait.h>


#define IP_SERVER "192.168.1.89"
#define PORT_SERVER 65000
#define BUFFERSIZE 1024
#define NUMFILES 3


double timeElapsed(struct timeval* before, struct timeval* after) {

  return after->tv_sec - before->tv_sec + (double) (after->tv_usec - before->tv_usec)/1000000;
}


void getFile(char *request, struct sockaddr_in server) {

  char buffer[1024];
  int sockProc, res;
  int file;
  int sizeServ = sizeof(server);
  int writeFile;

  sockProc = socket(AF_INET, SOCK_STREAM, 0);

  if (sockProc < 0) {
      printf("Error on creating socket client\n");
      perror("");
      exit(1);
  }

  file = open(request, O_CREAT | O_WRONLY, S_IRWXU);


  res = connect(sockProc, (struct sockaddr*)&server, (socklen_t)sizeServ);
  if (res < 0) {
      printf("Error on connecting to server!\n");
      perror("");
      exit(1);
  }

  res = send(sockProc, (void*)request, strlen(request), 0);

  memset(buffer, 0, sizeof(buffer));

  while((res = recv(sockProc, (void*)buffer, sizeof(buffer), 0)) > 0) {
      write(file, (void*)buffer, strlen(buffer));
      memset(buffer, 0, sizeof(buffer));
  }


  close(sockProc);
  close(file);
  return;

  }


  int main(int argc, char** argv) {

  int sockCli, res, i;

  struct sockaddr_in server;
  int sizeServ = sizeof(server);
  memset(&server, 0, sizeof(server));
  server.sin_family = AF_INET;
  inet_pton(AF_INET, IP_SERVER, &server.sin_addr);
  server.sin_port = htons(PORT_SERVER);

  char files[NUMFILES][32];
  char nameFile[32];

  char command[32] = "rm *.txt";

  system(command);

  struct timeval begin;
  struct timeval end;

  pid_t processes[NUMFILES];



  for(i = 0; i<NUMFILES; i++) {

      memset(nameFile, 0, sizeof(nameFile));
      printf("Inserisci nome file (con estensione) da ricevere:\n");
      scanf("%s", nameFile);
      strcpy(files[i], nameFile);

  }


  gettimeofday(&begin, NULL);

  for(i=0; i<NUMFILES; i++) {

      pid_t child = fork();

      if(child == 0) {
          getFile(files[i], server);
          exit(0);
      }

      else {
          processes[i] = child;
          continue;
      }

  }


  /*for(i=0; i<NUMFILES; i++) {
      waitpid(processes[i], NULL, 0);
  }*/

  wait(NULL);

  gettimeofday(&end, NULL);
  printf("Time elapsed on TCP is %f seconds\n", timeElapsed(&begin, &end));
  return 0;

  }

およびサーバー:

#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>

#define IP_SERVER "192.168.1.89"
#define PORT_SERVER 65000
#define BUFFERSIZE 1024

void execRequest(int* sockCli, struct sockaddr_in* client) {

  char buffer[BUFFERSIZE];
  char request[BUFFERSIZE];
  int res;

  memset(request, 0, sizeof(request));

  res = recv(*sockCli, (void*)request, sizeof(request), 0);

  if(res < 0) {
      printf("Error on recv()\n");
      perror("");
      exit(1);
  }
  printf("Requested file %s\n", request);

  char resource[32] = "files/";
  strcat(resource, request);

  int file = open(resource, O_RDONLY);

  if (file < 0) {
      printf("File %s does not exist\n", request);
      exit(1);
  }

  memset(buffer, 0, sizeof(buffer));

  while((res = read(file, (void*)buffer, sizeof(buffer))) > 0) {
      send(*sockCli, (void*)buffer, strlen(buffer), 0);
      memset(buffer, 0, sizeof(buffer));
  }

  close((*sockCli));
  close(file);
  free(sockCli);
  free(client);

  return;

  }

int main(int argc, char** argv) {

  int sockServ, i, res;
  int *sockCli;

  struct sockaddr_in server;
  struct sockaddr_in* client;


  sockServ = socket(AF_INET, SOCK_STREAM, 0);

  if(sockServ < 0) {
      printf("Error in creating socket\n");
      perror("");
      exit(1);
  }

  memset(&server, 0, sizeof(server));
  server.sin_addr.s_addr = inet_addr(IP_SERVER);
  server.sin_port = htons(PORT_SERVER);
  server.sin_family = AF_INET;

  int reuse = 1;
  res = setsockopt(sockServ, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int));
  if (res < 0) {
      printf("setsockopt() REUSEADDR failed\n");
      perror("");
      exit(1);
  }

  res = bind(sockServ, (struct sockaddr*)&server, sizeof(server));
  if (res < 0) {
      printf("Error on bindind TCP server!\n");
      perror("");
      exit(1);
  }

  res = listen(sockServ, 5);
  if (res < 0) {
      printf("Error on listening TCP server!\n");
      perror("");
      exit(1);
  }

  while(1) {

      sockCli = (int*)malloc(sizeof(int));
      client = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));
      int sizeClient = sizeof(struct sockaddr_in);

      *sockCli = accept(sockServ, (struct sockaddr*)client, &sizeClient);

      if ((*sockCli) < 0) {
                printf("accept() failed\n");
        perror("");
        continue;
      }

      printf("Connected to %s:%d\n", inet_ntoa(client->sin_addr), client->sin_port);

      if( !fork() ) {

          execRequest(sockCli, client);
          exit(0);

      }

      else
          continue;



}

  return 0;


  }

これは非常に奇妙です。クライアントによって作成されたプロセスは、サーバーがソケットを閉じても終了しないため、recv() は 0 を返して、クライアント プロセスをループから終了させる必要があります。さらに、ファイルの読み取りには奇妙な点があります。サーバーは単に files.txt を読み取りますが、これを行うと、読み取り文字に文字列 ".txt" が含まれ、このすべての混合物がクライアントに送信されます...なぜですか? それらは、aaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaa のような単純なファイルのモノ文字です。

しかし、サーバーは以下を読み取り、送信します。

aaaaaaaaaaaaaaaaaa.txt aaaaaaaaaaaaaaaaaa

これをすべて解決できますか?

4

2 に答える 2

1

を使用することはできませんstrlen(buffer)。テキスト ファイルから文字を読み込んでいるからbufferといって、有効な文字列であることを確認するための措置を講じない限り、それが有効な文字列になるとは限りません。そして、あなたはしません。ファイルからすべてのデータを入力できるため、終了はありませんbuffer

于 2013-03-28T12:37:57.200 に答える
0

ここスタック オーバーフローで壊れたレコードを何回再生する必要がありますか? malloc をキャストしないでください

このエラーは、マニュアルを読んでいないこと、インクルードするヘッダー、文字列 (したがって、strlen/strcat/str*{anything}* がその入力に期待するもの、printf が引数に期待するもの)見つけられないことに起因します。%sフォーマット指定子などに対応する)およびread/recv が生成するもの

res = recv(*sockCli, (void*)request, sizeof(request), 0);
if(res < 0) {
    printf("Error on recv()\n");
    perror("");
    exit(1);
}
printf("Requested file %.*s\n", res, request); // NOTE the field width provided by 'res'

res = read(file, (void*)buffer, sizeof(buffer))マニュアルでは、エラーまたは長さのいずれかを格納すると思われる例などがあります。この条件により、長さの値sendの場合にのみコードが実行されることが保証されます。?send(*sockCli, (void*)buffer, res, 0);

これらの問題の存在は、あなたの学習方法が機能していないことを示しているようです. あなたはどの本を読んでいますか。本なしでCを学ぶことは、コミュニケーションなしでどのベリーが有毒かを学ぶことに少し似ています.

于 2013-03-28T13:06:25.520 に答える