2016-03-08 90 views
-1

我試圖通過套接字發送一個修改後的字符串。目標是從客戶端獲取一個字符串,添加一些內容,然後發回。這些字符串通過命令行參數傳遞。現在,我可以收到消息從客戶端,但由於某些原因,我recvfrom函數返回-1這會導致客戶先掛了,而不是從服務器接收sendto。看起來服務器正在修改字符串,但我無法在另一側正確接收它。我的代碼中有用於測試目的的打印語句。客戶端的命令行參數是服務器名稱,端口號,字符串。服務器的命令行參數是端口號,要連接的字符串。下面是我的代碼:Ç - 發送修改後的字符串通過套接字

headerFiles.h:

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

server.c:

#include "headerFiles.h" 

int main(int argc, char* argv[]) 
{ 
    int s; 
    int len; 
    char buffer[256]; 
    struct sockaddr_in servAddr; 
    struct sockaddr_in clntAddr; 
    int clntAddrLen; 
    int serverPort; 
    char catStringMeow[256]; 

    serverPort = atoi(argv[1]); 
    strcpy(catStringMeow, argv[2]); 

    // Build local (server) socket address 
    memset(&servAddr, 0, sizeof(servAddr)); 
    servAddr.sin_family = AF_INET; 
    servAddr.sin_port = htons(serverPort); 
    servAddr.sin_addr.s_addr = htonl(INADDR_ANY); 

    // Create socket 
    if((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) 
    { 
     perror("Error: socket failed!"); 
     exit(1); 
    } 

    // Bind socket to local address and port 
    if((bind(s, (struct sockaddr*)&servAddr, sizeof(servAddr)) < 0)) 
    { 
     perror("Error: bind failed!"); 
     exit(1); 
    } 

    for(;;) // Runs forever 
    { 
     printf("buffer = %s\n", buffer); 
     printf("In for\n"); 
     // Receive String 
     len = recvfrom(s, buffer, sizeof(buffer), 0, (struct sockaddr*)&clntAddr, &clntAddrLen); 
     printf("Received %d bytes\n", len); 

     printf("buffer = %s\n", buffer); 
     strcat(buffer, " "); 
     strcat(buffer, catStringMeow); 
     printf("New string = %s\n",buffer); 
     printf("buffer size = %d\n", (int)strlen(buffer)); 
     len = (int)strlen(buffer); 

     // Send String 
     sendto(s, buffer, len, 0, (struct sockaddr*)&clntAddr, sizeof(clntAddr)); 
     printf("Sent %d bytes\n", len); 
    } 
} 

client.c:

#include "headerFiles.h" 

int main (int argc, char* argv[]) // Three arguments to be checked later 
{ 
    int s; // Socket descriptor 
    int len; // Length of string to be echoed 
    char* servName; // Server name 
    int servPort; // Server port 
    char* string; // String to be echoed 
    char buffer[256+1]; // Data buffer 
    struct sockaddr_in servAddr; // Server socket address 

    // Check and set program arguments 
    if(argc != 4) 
    { 
     printf("Error: three arguments are needed!\n"); 
     exit(1); 
    } 

    servName = argv[1]; 
    servPort = atoi(argv[2]); 
    string = argv[3]; 

    // Build server socket address 
    memset(&servAddr, 0, sizeof(servAddr)); 
    servAddr.sin_family = AF_INET; 
    inet_pton(AF_INET, servName, &servAddr.sin_addr); 
    servAddr.sin_port = htons(servPort); 

    // Create socket 
    if((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) 
    { 
     perror("Error: Socket failed!"); 
     exit(1); 
    } 

    // Send echo string 
    len = sendto(s, string, strlen(string), 0, (struct sockaddr*) &servAddr, sizeof(servAddr)); 
    printf("Sent %d bytes\n", len); 

    // Receive echo string 
    len = recvfrom(s, buffer, len, 0, NULL, NULL); 
    printf("Received\n"); 

    //Print and verify echoed string 
    buffer[len] = '\0'; 
    printf("Echo string received: "); 
    fputs(buffer, stdout); 
    printf("\n"); 

    // Close the socket 
    close(s); 

    // Stop the program 
    exit(0); 
} 
+1

'的strcat(緩衝液,「「);'緩衝器** **不空終止。你有'len = recvfrom(...)'::使用它。 – wildplasser

+0

'len'評估爲-1,因爲'recvfrom'正在返回。我無法使用它。 'recvfrom'函數有問題。 –

+3

當系統調用返回'-1'時,表示出現錯誤,'errno'包含錯誤代碼。調用'perror()'來打印原因。 – Barmar

回答

0

// Receive echo string 
    len = recvfrom(s, buffer, sizeof(buffer), 0, NULL, NULL); 
    printf("Received\n"); 

並使緩衝區更大。

+0

它仍然無法正常工作。 –

+0

,它是否因相同的原因失敗? – pm100

+0

現在我恢復到我剛纔的字符串回聲的原始代碼。它工作正常。當我添加: 'char catThisString [256];' 'strcpy(cat,argv [2]);' 它弄得一團糟。沒有什麼會來回發送。 –

0

你傳遞一個uninitizlied clntAddrLenrecvfrom,這是導致Invalid argument錯誤代碼。根據documentation

的參數addrlen是一個值結果參數,其中所述呼叫者應呼叫與src_addr相關聯的緩衝器的大小之前初始化,和改性的上返回,以指示的實際尺寸源地址。

所以,你需要將其初始化:

clntAddrLen = sizeof(clntAddr); 
0

確保你的sendto或recvfrom的使用它之前初始化客戶端地址長度是可變的。

的問題是,在第一通話從client.c到SENDTO,服務器認爲客戶端的IP爲0.0.0.0,之後在第二,第三,......會調用client.c獲得IP和有一個合法的IP如127.0.0.3:3212。

你可以看到,第二,第三,......客戶端。

初始化可變長度爲sizeof(結構SOCKADDR_IN)