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

C-通过套接字发送修改的字符串,c,string,sockets,C,String,Sockets,我正在尝试通过套接字发送修改后的字符串。目标是从客户端获取一个字符串,向其中添加一些内容,然后将其发送回。字符串在命令行参数中传递。现在,我可以从客户端接收消息,但由于某种原因,我的recvfrom函数返回-1,这会导致客户端挂起,并且无法从服务器接收发送到。看起来服务器正在很好地修改字符串,但我无法让它在另一端正确接收。出于测试目的,我在代码中有打印语句。客户端的命令行参数包括服务器名称、端口号和字符串。服务器的命令行参数是端口号、要连接的字符串。下面是我的代码: 头文件.h: #includ

我正在尝试通过套接字发送修改后的字符串。目标是从客户端获取一个字符串,向其中添加一些内容,然后将其发送回。字符串在命令行参数中传递。现在,我可以从客户端接收消息,但由于某种原因,我的
recvfrom
函数返回
-1
,这会导致客户端挂起,并且无法从服务器接收
发送到
。看起来服务器正在很好地修改字符串,但我无法让它在另一端正确接收。出于测试目的,我在代码中有打印语句。客户端的命令行参数包括服务器名称、端口号和字符串。服务器的命令行参数是端口号、要连接的字符串。下面是我的代码:

头文件.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>
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
服务器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);
    }
}
#包括“headerFiles.h”
int main(int argc,char*argv[])
{
int-s;
内伦;
字符缓冲区[256];
servAddr中的结构sockaddr_;
clntAddr中的结构sockaddr_;
int CLNTADDREN;
int服务器端口;
char-catStringMeow[256];
serverPort=atoi(argv[1]);
strcpy(catStringMeow,argv[2]);
//生成本地(服务器)套接字地址
memset(&servAddr,0,sizeof(servAddr));
servAddr.sin_family=AF_INET;
servAddr.sin_port=htons(服务器端口);
servAddr.sin\u addr.s\u addr=htonl(INADDR\u ANY);
//创建套接字
如果((s=插座(PF_INET,SOCK_DGRAM,0))<0)
{
perror(“错误:套接字失败!”);
出口(1);
}
//将套接字绑定到本地地址和端口
if((bind(s,(struct sockaddr*)&servAddr,sizeof(servAddr))<0))
{
perror(“错误:绑定失败!”);
出口(1);
}
因为(;)//永远运行
{
printf(“缓冲区=%s\n”,缓冲区);
printf(“In for\n”);
//接收字符串
len=recvfrom(s,buffer,sizeof(buffer),0,(struct sockaddr*)和clntAddr,&clntAddrLen);
printf(“接收到%d字节\n”,len);
printf(“缓冲区=%s\n”,缓冲区);
strcat(缓冲区“”;
strcat(缓冲器、catStringMeow);
printf(“新字符串=%s\n”,缓冲区);
printf(“缓冲区大小=%d\n”,(int)strlen(缓冲区));
len=(int)strlen(缓冲区);
//发送字符串
sendto(s,buffer,len,0,(struct sockaddr*)和clntAddr,sizeof(clntAddr));
printf(“已发送%d字节\n”,len);
}
}
客户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);
}
#包括“headerFiles.h”
int main(int argc,char*argv[])//三个参数稍后检查
{
int s;//套接字描述符
int len;//要回显的字符串的长度
char*servName;//服务器名称
int servPort;//服务器端口
char*string;//要回显的字符串
字符缓冲区[256+1];//数据缓冲区
servAddr中的struct sockaddr\u;//服务器套接字地址
//检查并设置程序参数
如果(argc!=4)
{
printf(“错误:需要三个参数!\n”);
出口(1);
}
servName=argv[1];
servPort=atoi(argv[2]);
string=argv[3];
//生成服务器套接字地址
memset(&servAddr,0,sizeof(servAddr));
servAddr.sin_family=AF_INET;
inet\u pton(AF\u inet、servName和servAddr.sin\u addr);
servAddr.sin_port=htons(servPort);
//创建套接字
如果((s=插座(PF_INET,SOCK_DGRAM,0))<0)
{
perror(“错误:套接字失败!”);
出口(1);
}
//发送回显字符串
len=sendto(s,string,strlen(string),0,(struct sockaddr*)和servAddr,sizeof(servAddr));
printf(“已发送%d字节\n”,len);
//接收回显字符串
len=recvfrom(s,buffer,len,0,NULL,NULL);
printf(“已收到”);
//打印并验证回显字符串
缓冲区[len]='\0';
printf(“接收到回音字符串:”);
FPUT(缓冲区、标准输出);
printf(“\n”);
//合上插座
关闭(s);;
//停止节目
出口(0);
}
do


并使缓冲区更大。

您正在将一个未初始化的
clntAddressLen
值传递给
recvfrom
,这将导致
无效参数
错误代码。根据报告:

参数
addrlen
是一个值结果参数,调用方应在调用与
src_addr
关联的缓冲区大小之前初始化该参数,并在返回时进行修改以指示源地址的实际大小

因此,您需要使用以下命令对其进行初始化:

clntAddrLen = sizeof(clntAddr);

在sendto或recvfrom中使用客户端地址长度变量之前,请确保对其进行初始化

问题是,在第一次从client.c调用sendto时,服务器将客户端的ip视为0.0.0.0,然后在第二次、第三次调用时,。。。调用client.c获取ip并拥有合法ip,如127.0.0.3:3212

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


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

strcat(buffer,”)缓冲区未以nul终止。您有
len=recvfrom(…)
::使用它。
len
的计算结果为-1,因为这是
recvfrom
返回的结果。我不能用它。
recvfrom
函数有问题。当系统调用返回
-1
时,意味着它收到了错误,
errno
包含错误代码。调用
perror()
打印原因。请注意,您发送的消息长度为len-long,添加一些内容,然后尝试接收到len-long缓冲区中。这是行不通的您将得到
errno
1,这意味着
参数无效
,因为
recvfrom()
需要客户端地址的大小,但您发送了未知值。尝试使用
int-clntAddrLen=sizeof(clntAddr)
初始化
int-clntAddrLen
。是否由于同样的原因而失败?现在我正在恢复到只有字符串回显的原始代码。它很好用。当我加上:clntAddrLen = sizeof(clntAddr);