2014-02-24 30 views
0

我在一臺服務器上有一個Unix shell,它應該將輸出發送到客戶端,然後打印出來。我已經嘗試了幾種不同的方法來獲得完整的輸出,但即使我在recv中使用while循環,我也只能得到3-5個字母,這應該能夠接收所有內容。不會收到從服務器到客戶端的完整數據(unix-C)

服務器打印出整個輸出,但客戶端沒有收到整個數據。

Server代碼:

#include <signal.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#define EXIT_SUCCESS 0 
#define EXIT_FAILURE 1 


#include <errno.h> 
#include <string.h> 
#include <sys/socket.h> 
#include <sys/un.h> 
#include <sys/wait.h> 
#define SOCK_PATH "echo_socket" 
#define ORDLANGD 30 
#define die(e) do { fprintf(stderr, e); exit(EXIT_FAILURE); } while (0); 

void byt(char *foo); 
void lasIn(char *a1, char *argv[]); 

static void pSigHandler(int signo){ 
    switch (signo) { 
      case SIGTSTP: 
      printf("TSTP"); 
      fflush(stdout); 
      break; 
    } 
} 

int main(void) 
{ 
    int s, s2, t, len, newsockfd; 
    struct sockaddr_un local, remote; 
    char str[100]; 
    char *argv[7]; 
    char foo[4096]; 
    int link[2]; 

    if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { 
    perror("socket"); 
    exit(1); 
    } 

    local.sun_family = AF_UNIX; 
    strcpy(local.sun_path, SOCK_PATH); 
    unlink(local.sun_path); 
    len = strlen(local.sun_path) + sizeof(local.sun_family); 
    if (bind(s, (struct sockaddr *)&local, len) == -1) { 
    perror("bind"); 
    exit(1); 
    } 

    if (listen(s, 5) == -1) { 
    perror("listen"); 
    exit(1); 
    } 

    struct sigaction psa; 
    psa.sa_handler = pSigHandler; 
    sigaction(SIGTSTP, &psa, NULL); 

    for(;;) { 
    int done, n; 
    printf("Waiting for a connection...\n"); 
    t = sizeof(remote); 
    if ((s2 = accept(s, (struct sockaddr *)&remote, &t)) == -1) { 
     perror("accept"); 
     exit(1); 
    } 

    printf("Connected.\n"); 

     pid_t pid; 
     pid = fork(); 
     if (pid < 0) 
     { 
      perror("ERROR on fork"); 
     exit(1); 
     } 

       if (pid == 0) 
     { 
      /* This is the client process */ 
      close(s); 

           done = 0; 
        do { 
         n = recv(s2, str, 100, 0); 
         if (n <= 0) { 
        if (n < 0) perror("recv"); 
        done = 1; 
         } 

       lasIn(str, argv); 
       if ((strcmp(argv[0], "exit")) == 0){ 
        exit(0); 
       } 
       else if ((strcmp(argv[0], "cd")) == 0){ 
        if ((chdir(argv[1])) != 0){ 
         printf("Gar inte att byta katalog\n"); 
         } 
       } 

       pid_t pid; 

       if (pipe(link)==-1) 
       die("pipe"); 

       if ((pid = fork()) == -1) 
       die("fork"); 

       if(pid == 0) { 

       dup2 (link[1], STDOUT_FILENO); 
       close(link[0]); 
       execvp(argv[0], argv); 
       sleep (1); 
       exit(0); 

       } else { 

       close(link[1]); 
       read(link[0], foo, sizeof(foo)); 
       printf("\n\n%s\n\n", foo); 

       wait(NULL); 

       } 

         if (!done) 
         { 

        if (send(s2, foo, n, 0) < 0) { 
         perror("send"); 
         done = 1; 
        } 
         } 
        } while (!done); 




     } 
     else 
     { 
      close(s2); 
     } 


    } 

    return 0; 
} 


void lasIn(char *a1, char *argv[]){ 
    int i; 
    argv[0] = strtok(a1, " \n"); 
    for(i = 1; i < 6; i = i++) { 
     argv[i] = strtok(NULL, " \n"); 
     if (argv[i] == NULL) 
     break; 
    } 
    argv[6] = NULL; 
} 

客戶端代碼:

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

#define SOCK_PATH "echo_socket" 


int main(void) 
{ 

    int s, t, len; 
    struct sockaddr_un remote; 
    char str[100]; 

    if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { 
    perror("socket"); 
    exit(1); 
    } 

    printf("Trying to connect...\n"); 

    remote.sun_family = AF_UNIX; 
    strcpy(remote.sun_path, SOCK_PATH); 
    len = strlen(remote.sun_path) + sizeof(remote.sun_family); 
    if (connect(s, (struct sockaddr *)&remote, len) == -1) { 
    perror("connect"); 
    exit(1); 
    } 

    printf("Connected.\n"); 

    while(printf("> "), fgets(str, 100, stdin), !feof(stdin)) { 
    if (send(s, str, strlen(str), 0) == -1) { 
     perror("send"); 
     exit(1); 
    } 

     while(1) 
     { 
      memset(str ,0 , 100); //clear the variable 
      if(recv(s , str , 100 , 0) < 0) 
      { 
       break; 
      } 
      else 
      { 
       printf("%s" , str); 
       break; 

      } 
     } 
    } 

    close(s); 

    return 0; 
} 

回答

1

既然你得到了一些,不是所有的預期流量,也許是一個潛在的問題是兩個break;代碼段中的說明:

while(1) 
{ 
    memset(str ,0 , 100); //clear the variable 
    if(recv(s , str , 100 , 0) < 0) 
    { 
     break;//here 
    } 
    else 
    { 
     printf("%s" , str); 
     break;//and here 

    } 
} 

第一次進入時,它會在一個或其他分支中跳出while循環,不管是否有更多的數據。使用備用調用結構
1)

你可能會考慮兩個額外的東西。喜歡的東西:

while(recv(s , str , 100 , 0) > 0) 
{ 
    ... 
} 
//do some error checking here 

2)放小(部分第二)延遲留下一個成功send(,,,);並呼籲recv(,,,)之間。

使用結束符與插座EDIT例如

numBytesReceived = recv(irdaCommSocket, recvBuf, readBufsize, 0); 
while(strstr(recvBuf, "%") == NULL)//uniques terminating character (use anything, including `\n`) 
{ 
    if (numBytesReceived < 0) return WSAGetLastError();//windows specific, change error handling for linux 
    strncpy(bufptr, recvBuf, readBufsize); 
    *pNumBytes += numBytesReceived; 
    numBytesReceived = recv(irdaCommSocket, recvBuf, readBufsize, 0); 
} 
+0

我試着 而(RECV(S,STR,100,0)> 0) 但這種說法是從未實現,它永遠不會進入while循環。 – user3344447

+0

這與 if(recv(s,str,100,0)<0) 它只是跳轉到其他 – user3344447

+0

我也嘗試將睡眠(4)放入客戶端和服務器,但它沒有幫助 – user3344447

相關問題