2016-03-08 122 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)