首页 文章

C - 通过套接字发送修改后的字符串

提问于
浏览
-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);
}

3 回答

  • 0

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

    并使缓冲区更大 .

  • 0

    您将未经启发的 clntAddrLen 值传递给 recvfrom ,这会产生 Invalid argument 错误代码 . 根据documentation

    参数addrlen是一个value-result参数,调用者应该在调用与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 .

    你可以看到第二,第三,......客户工作 .

    将length变量初始化为sizeof(struct sockaddr_in)

相关问题