【发布时间】:2021-12-30 13:27:00
【问题描述】:
#include <sys/socket.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>
#include <vector>
#include <sys/types.h>
#include <unistd.h>
#include <cstring>
int main(int argc, char* argv[]){
int socketfd = 0;
int portin = 5514; //default port
int que = 20; //default queue size
int n = 0;
int d = 1; //for use in setsockopt
socklen_t clientsize = 0;
struct sockaddr_in servadd, cliadd;
if (argc > 2)
portin = atoi(argv[2]);
if (argc > 1)
que = atoi(argv[1]);
socketfd = socket(AF_INET, SOCK_STREAM, 0);
setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &d, sizeof(int));
bzero((char*) &servadd, sizeof(servadd));
servadd.sin_family = AF_INET;
servadd.sin_addr.s_addr = INADDR_ANY;
servadd.sin_port = htons(portin);
bind(socketfd, (struct sockaddr*) &servadd, sizeof(servadd));
std::cout << "Wall server running on port " << portin << " with queue size " << que << ".\n";
char wallc[] = "Wall Contents\n-------------\n";
char entc[] = "Enter command: ";
do {
listen(socketfd,1);
clientsize = sizeof(cliadd);
int newadd = accept(socketfd, (struct sockaddr*)&cliadd, &clientsize);
while (newadd > 0) {
char buffer[80];
n = write(newadd, wallc, sizeof(wallc));
n = write(newadd, entc, strlen(entc));
int a = recv(newadd, buffer, strlen(buffer), 0); //this blocks for input on first and
// second pass, but on third, it will just skip over and cause endless output from write commands.
memset(buffer, 0, 80);
};
}while (socketfd > 0);
return 0;
}
此代码在一个终端中运行并与另一个终端连接时,会将两个缓冲区都输出到客户端。然后它会在第一次循环中等待一个命令,然后在循环中第二次返回recv命令,但无论输入如何,第二次进入后,它都会将两个缓冲区无限写入客户终端,直到我将其关闭。完整代码中还有其他功能使该服务器成为公告板系统,但是这里的这段代码在运行时给了我无限循环,我不知道出了什么问题。
【问题讨论】:
-
网络编程规则之一:始终全面评估返回码。
-
strlen(buffer)不是获取缓冲区大小的正确方法。strlen搜索它可以找到的第一个空字符。这意味着缓冲区必须在其范围内有一个空字符,这是该程序无法保证的。还要考虑当第一个字符恰好是空字符时会发生什么。使用sizeof(buffer) -
@user4581301 感谢您的帮助,这解决了无限循环问题,尽管我得到了有趣的行为以获取正确的输入,我需要第一次从缓冲区末尾修剪两个字符,并且每次只有一个。
-
目前还没有人回答这个问题,因此您可以安全地使用现有的代码更新代码。到目前为止,您发布的内容中的错误检查中有很多小遗漏,这可能会导致新问题。如果您在此期间纠正了其中的一些问题,那么除了重写代码之外,我们还需要这些信息来帮助您,您可能不会从中学到太多东西。