Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从C中的套接字读取输出_C_Sockets - Fatal编程技术网

从C中的套接字读取输出

从C中的套接字读取输出,c,sockets,C,Sockets,我无法从插座读取数据。我使用的代码如下所示,有时工作正常,但在其他时间,它只打印一些不可读的字符,或一些随机可读的字符。。。有更好的办法吗 char* answer = (char*) malloc(1024); int answerLength = 0; char prevChar = 0; char newChar = 0; while (answerLength < 1024 && read(sock, &newChar

我无法从插座读取数据。我使用的代码如下所示,有时工作正常,但在其他时间,它只打印一些不可读的字符,或一些随机可读的字符。。。有更好的办法吗

    char* answer = (char*) malloc(1024);
    int answerLength = 0;
    char prevChar = 0;
    char newChar = 0;
    while (answerLength < 1024 && read(sock, &newChar, 1) > 0 ) {

            if (newChar == '\n' && prevChar == '\r') {
                    break;
            }
            printf("%d\n", answerLength);
            answer[ answerLength ] = newChar;
            answerLength++;

            prevChar = newChar;
    }
    printf("%s\n", answer);

C中的字符串必须以null结尾,这意味着它们的最后一个字符必须是符号\0

因为您不能保证它会发生在代码中的任何地方,所以在您读取的数据旁边,答案可能会被内存垃圾填充

要确保不会发生这种情况,请使用:

answer[answerLength] = '\0';
printf("%s\n", answer);
另外,你可以直接阅读整件事来回答,你不需要那种毫无意义的循环:

int len;
while (len = read(sock, &answer[answerLength], 1024 - answerLength))
    answerLength += len;
answer[answerLength] = '\0';
printf("%s\n", answer);

C中的字符串必须以null结尾,这意味着它们的最后一个字符必须是符号\0

因为您不能保证它会发生在代码中的任何地方,所以在您读取的数据旁边,答案可能会被内存垃圾填充

要确保不会发生这种情况,请使用:

answer[answerLength] = '\0';
printf("%s\n", answer);
另外,你可以直接阅读整件事来回答,你不需要那种毫无意义的循环:

int len;
while (len = read(sock, &answer[answerLength], 1024 - answerLength))
    answerLength += len;
answer[answerLength] = '\0';
printf("%s\n", answer);

您读取的数据不是以“\0”字符结尾的,因此您不能将其视为字符串。

您读取的数据不是以“\0”字符结尾的,因此您不能将其视为字符串。

您的字符数组不保证以null结尾。这意味着printf可能打印的不仅仅是数组中的内容,因为它寻找空终止以停止输出字符

您在使用分配的内存之前也不会初始化它,这是一种不好的做法,因为内存可能包含随机垃圾

要使代码更好地工作并有希望解决您的问题,您应该执行以下操作:

char* answer = malloc(1024 + 1); /* add extra byte for null terminator */
/* other variables the same */

memset( answer, '\0', 1024 + 1 ); /* initialise memory before use */
while (answerLength < 1024 && read(sock, &newChar, 1) > 0 ) {
    /* loop is the same */
}
printf("%s\n", answer);

您的字符数组不保证以null结尾。这意味着printf可能打印的不仅仅是数组中的内容,因为它寻找空终止以停止输出字符

您在使用分配的内存之前也不会初始化它,这是一种不好的做法,因为内存可能包含随机垃圾

要使代码更好地工作并有希望解决您的问题,您应该执行以下操作:

char* answer = malloc(1024 + 1); /* add extra byte for null terminator */
/* other variables the same */

memset( answer, '\0', 1024 + 1 ); /* initialise memory before use */
while (answerLength < 1024 && read(sock, &newChar, 1) > 0 ) {
    /* loop is the same */
}
printf("%s\n", answer);

同意。重要的是要记住,从malloc返回的内存将被未定义的内容填充;除非代码显式地将其归零,否则它不会归零,因此,由于代码不会手动以null结尾,printf可以在结尾打印任意数量的垃圾,这完全取决于之前内存中的内容。或者不要使用printf,而是使用一个以长度为参数的函数,关键问题是printf需要确定字符串结束的位置,因为它找不到“\0”,它一直在垃圾中读取…@iharob:printf可以将长度作为参数:printf%.*s\n,answerLength,answer您的单次读取不等同于原始读取-原始读取到第一个\r\n序列,1023个字符或错误,以先发生的为准,但您的错误只会在一次读取中获取它所获取的内容,可能根本不包含序列,或者可能包含多个。已同意。重要的是要记住,从malloc返回的内存将被未定义的内容填充;除非代码显式地将其归零,否则它不会归零,因此,由于代码不会手动以null结尾,printf可以在结尾打印任意数量的垃圾,这完全取决于之前内存中的内容。或者不要使用printf,而是使用一个以长度为参数的函数,关键问题是printf需要确定字符串结束的位置,因为它找不到“\0”,它一直在垃圾中读取…@iharob:printf可以将长度作为参数:printf%.*s\n,answerLength,answer您的单次读取不等同于原始读取-原始读取到第一个\r\n序列,1023个字符或错误,以先发生的为准,但您的读取只需在一次读取中获取它所获得的任何内容,可能根本不包含序列,\r\n或者可能包含多个序列。请从malloc中删除强制转换,读取请从malloc中删除强制转换,在C中读取,不要从malloc和函数族中强制转换返回值。”应该定义“1024”这样的神奇数字,以大大减轻调试和以后维护的负担。define name go编程风格表示:所有大写字母都应该表示1024的含义,包括这一行:'if newChar='\n'&&prevChar='\r'{'操作系统/编译器将处理操作系统行尾之间的差异,有些操作系统仅使用换行符,有些操作系统仅使用回车符,有些操作系统使用多字符字符串。编译器将处理详细信息,因此代码只需使用'\n'建议使用calloc而不是malloc,因此分配的内存已'初始化为all\0',因此存在不必担心向输入字符串添加空终止符。顺便说一句:当answerLength为1023时,应该停止,而不是添加另一个字符,因为添加该字符将导致“answer”缓冲区没有空间容纳NUL字符串终止符C,所以不可以
st从malloc和函数族返回的值。'应该定义“1024”这样的神奇数字,以大大减轻调试和以后维护的负担。define name go编程风格表示:所有大写字母都应该表示1024的含义,包括这一行:'if newChar='\n'&&prevChar='\r'{'操作系统/编译器将处理操作系统行尾之间的差异,有些操作系统仅使用换行符,有些操作系统仅使用回车符,有些操作系统使用多字符字符串。编译器将处理详细信息,因此代码只需使用'\n'建议使用calloc而不是malloc,因此分配的内存已'初始化为all\0',因此存在不必担心向输入字符串添加空终止符。顺便说一句:当answerLength为1023时,应该停止,而不是添加另一个字符,因为添加该字符将导致“应答”缓冲区没有容纳NUL字符串终止字符的空间