- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我必须实现两个必须通过 TCP 进行交互的进程,基本上是服务器和客户端之间的文件传输(学校作业)。第一次文件传输一切正常,但是当客户端结束其作业时,服务器因错误 - Accept() 失败:错误的文件描述符
而崩溃。
server_main.c
int main (int argc, char *argv[]) {
char cwd[100];
if (getcwd(cwd, sizeof(cwd)) != NULL) {
printf("App[starting]: " ANSI_COLOR_CYAN "%s" ANSI_COLOR_RESET "\n", cwd);
} else {
printf("App[quitting]: " ANSI_COLOR_RED "UNABLE TO LOCATE WDIR" ANSI_COLOR_RESET "\n");
return 1;
}
// procedo solo se vengono passati esattamente due parametri allo script
// 1. il nome dello script (default)
// 2. la porta
if (argc == 2) {
int passiveSocket = startTcpServer(argv[1]);
runIterativeTcpInstance(passiveSocket);
close(passiveSocket);
return 0;
}
// se arrivo qui ho app crash
printf("App[quitting]: " ANSI_COLOR_RED "USAGE: <PORT>" ANSI_COLOR_RESET "\n");
return 1;
}
gj_server.c
int startTcpServer(const char* port) {
uint16_t i_port;
int sockfd;
sockfd = Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
parsePort(port, &i_port);
bindToAny(sockfd, i_port);
Listen(sockfd, 516);
printf("Server[listening]: " ANSI_COLOR_GREEN "PORT = %d, BACKLOG = 516" ANSI_COLOR_RESET "\n", (int) i_port);
return sockfd;
}
void runIterativeTcpInstance(int passiveSock) {
struct sockaddr_in cli_addr;
socklen_t addr_len = sizeof(struct sockaddr_in);
while(1) {
printf("Server[accepting]: " ANSI_COLOR_YELLOW "WAITING FOR A CONNECTION..." ANSI_COLOR_RESET "\n");
int connSock = Accept(passiveSock , (struct sockaddr *) &cli_addr, &addr_len);
doTcpJob(connSock);
close(connSock);
}
}
void doTcpJob(int connSock) {
//TODO: uscire in caso di errore di una delle due fasi
printf("Server[connection]:" ANSI_COLOR_GREEN "STARTED A NEW ON CONNECTION (PID=%d)" ANSI_COLOR_RESET "\n", getpid());
char request[256];
initStr(request, 256);
if(doTcpReceive(connSock, request) == 0)
doTcpSend(connSock, request);
else {
printf("Server[error]: " ANSI_COLOR_RED "INVALID REQUEST FROM CLIENT: %s" ANSI_COLOR_RESET "\n", request);
char err_buff[7] = "-ERR\r\n";
send(connSock, err_buff, 6, 0);
//close(connSock);
}
//关闭(connSock); }
int doTcpReceive(int connSock, char *request) {
struct timeval tval;
fd_set cset;
FD_ZERO(&cset);
FD_SET(connSock, &cset);
tval.tv_sec = 15;
tval.tv_usec = 0;
if(Select(FD_SETSIZE, &cset, NULL, NULL, &tval) == 1) {
// TODO: INSERIRE LOGICA RECEIVE QUI
ssize_t read = 0;
while (reqCompleted(request) == -1 ) {
ssize_t received = Recv(connSock, request, 256, 0);
read += received;
}
printf("Server[receive]: " ANSI_COLOR_CYAN "RECEIVED %s" ANSI_COLOR_RESET "\n", request);
return checkRequest(request);
}
// esco per timeout
//close(connSock);
return -1;
}
void doTcpSend(int connSock, char *request) {
// TODO: INSERIRE LOGICA SEND QUI
// 1. send ok message
char ok_msg[6] = "+OK\r\n";
send(connSock, ok_msg, 5, 0);
// 2. send file size
FILE *fp = fopen(request, "rb+");
// qui il file dovrebbe esistere, ma potrebbe essere inacessibile o
// l'apertura potrebbe fallire
if (fp == NULL) {
printf("SERVER[READING]" ANSI_COLOR_RED "CANNOT OPEN FILE %s " ANSI_COLOR_RESET "\n", request);
char err_buff[7] = "-ERR\r\n";
send(connSock, err_buff, 6, 0);
//close(connSock);
return;
}
struct stat stat_buf;
if (fstat(fileno(fp), &stat_buf) == 0) {
long f_size = stat_buf.st_size;
long f_time = stat_buf.st_mtime;
uint32_t net_f_size = htonl(f_size);
send(connSock, &net_f_size, 4, 0);
// 3. send file content
ssize_t sent = 0;
printf("fsize: %d", (int)f_size);
while (sent < f_size) {
sent += sendfile(connSock, fileno(fp), NULL, f_size);
showProgress((int)sent, (int)f_size, "Server[sending]: ");
}
fclose(fp);
// 4. send file timestamp
uint32_t net_f_time = htonl(f_time);
send(connSock, &net_f_time, 4, 0);
//close(connSock);
} else {
char err_buff[7] = "-ERR\r\n";
send(connSock, err_buff, 6, 0);
//close(connSock);
return;
}
}
int reqCompleted(char *request) {
int len = strlen(request);
return len > 6 && request[len - 2] == '\r' && request[len - 1] == '\n' ? 0 : -1;
}
int checkRequest(char *request) {
int len = strlen(request);
if (len > 6 && request[0] == 'G' && request[1] == 'E' && request[2] == 'T'
&& request[3] == ' ' && request[len - 2] == '\r' && request[len - 1] == '\n') {
memcpy(request, request + 4, (len - 6)); // estraggo il nome del file dalla richiesta
request[len - 6] = '\0';
return access(request, F_OK); // verifico che il file esista nella cartella di lavoro
}
return -1;
}
名为passiveSock
的参数导致了问题,在while循环的第二次迭代中,我对C很陌生,我认为它与变量的生命周期有关。我已经尝试在接受调用之前打印 passiveSock
并给我一个错误。这是 valgrind 输出:
==1== Syscall param accept(s) contains uninitialised byte(s)
==1== at 0x4F21990: __accept_nocancel (syscall-template.S:84)
==1== by 0x10A7D4: Accept (sockwrap.c:97)
==1== by 0x109AA5: runIterativeTcpInstance (gj_server.c:28)
==1==
((null)) error - accept() failed: Bad file descriptor
==1==
==1== HEAP SUMMARY:
==1== in use at exit: 0 bytes in 0 blocks
==1== total heap usage: 2 allocs, 2 frees, 1,576 bytes allocated
==1==
==1== All heap blocks were freed -- no leaks are possible
==1==
==1== For counts of detected and suppressed errors, rerun with: -v
==1== Use --track-origins=yes to see where uninitialised values come from
==1== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
编辑 sockwrap.c 接受定义
int Accept (int listen_sockfd, SA *cliaddr, socklen_t *addrlenp)
{
int n;
again:
if ( (n = accept(listen_sockfd, cliaddr, addrlenp)) < 0)
{
if (INTERRUPTED_BY_SIGNAL ||
errno == EPROTO || errno == ECONNABORTED ||
errno == EMFILE || errno == ENFILE ||
errno == ENOBUFS || errno == ENOMEM
)
goto again;
else
err_sys ("(%s) error - accept() failed", prog_name);
}
return n;
}
initStr 和 showProgress
void initStr(char* string, int length) {
memset(string, '\0', length);
string[length] = '\0';
}
void showProgress(int done, int tot, char * progMsg) {
int progress = ((double) done / (double) tot) * 100;
printf("\r%s " ANSI_COLOR_CYAN "%d bytes (%d%%)" ANSI_COLOR_RESET, progMsg, done, progress);
fflush(stdout);
}
最佳答案
当然,这个错误是在我想检查的第一个函数中。仔细看:
void initStr(char* string, int length) {
memset(string, '\0', length);
string[length] = '\0'; // <-- BOOM!
}
但是:
char request[256];
initStr(request, 256);
因此 request
是一个包含 256 个条目的数组。但是 initStr
写入了第 257 个条目,该条目不存在。
你应该摆脱这个功能,并且永远不要使用任何类似它的东西。用零填充整个缓冲区没有任何意义。相反,正确跟踪缓冲区中数据的长度并停止始终调用 strlen
。因此,您的代码中还存在其他更微妙的错误。
例如,您尝试从连接读取 256 字节。这可能会填充整个缓冲区,替换所有零字节。然后,您将缓冲区传递给 strlen
——但不能保证缓冲区中的任何位置都有零字节。
通过网络连接接收的数据不是字符串。它是从 read
或 recv
函数返回的已知长度的原始数据。不要假装它是一个字符串。这是一个坏习惯,会一次又一次地咬你。
关于c - 错误 - 接受()失败 : Bad file descriptor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59506598/
我想知道是否可以访问放在 tomcat 的 conf 文件夹中的文件。通常我会在这个文件中放置多个 webapp 的配置,在 war 之外。 我想使用类路径独立于文件系统。 我过去使用过 lib 文件
我有一个 PowerShell 脚本,它获取文件列表并移动满足特定条件的文件。为什么即使对象为空,foreach 循环也会运行? 我假设如果 $i 不存在,它就不会运行。但是如果 $filePath
我已将 BasicAccountRule.drl 放置在我的 Web 应用程序中,位置为:C:/workspace/exim_design/src/main/resources/rules/drl/i
我使用 File.open('file.txt').class 和 File.open('file.txt').readlines.class 以及前者进行了检查一个返回 File,后者返回 Arra
我正在尝试使用 FileOutputStream 删除文件,在其中写入内容后。这是我用来编写的代码: private void writeContent(File file, String fileC
我正在尝试使用 flink 和 python 批处理 api 测试 Wordcount 经典示例。我的问题是,将数据源从 env.from_elements() 修改为 env.read_text()
我正在尝试制作一个可以同时处理多个不同文件的程序。我的想法是制作一个包含 20 个 FILE* 的数组,以便在我达到此限制时能够关闭其中一个并打开请求的新文件。 为此,我想到了一个函数,它选择一个选项
我有两个文件A和B文件A: 976464 792992 文件B TimeStamp,Record1,976464,8383,ABCD 我想搜索文件 A 和文件 B 中的每条记录并打印匹配的记录。打印的
我有一些保存在 map 中的属性文件。示例: Map map = new HashMap<>(); map.put("1", "One"); map.put("2", "Two"); map.put(
我正在尝试找出一个脚本文件,该文件接受一个包含文件列表的文件(每一行都是一个文件路径,即 path/to/file)并将它们合并到一个文件中。 例如: list.text -- path/to/fil
为了使用 File.CreateText() 和 File.AppendText() 你必须: 通过调用这些方法之一打开流 写消息 关闭流 处理流 为了使用 File.AppendAllText()
使用rsync时,如何在使用--files-from参数复制时重命名文件?我有大约190,000个文件,在从源复制到目标时,每个文件都需要重命名。我计划将文件列表放在一个文本文件中传递给--files
我在非服务器应用程序中使用 Spring(只需从 Eclipse 中某个类的 main() 编译并运行它)。 我的问题是作为 new FileSystemXmlApplicationContext 的
QNX (Neutrino 6.5.0) 使用 ksh 的开源实现作为其 shell 。许多提供的脚本,包括系统启动脚本,都使用诸如 if ! test /dev/slog -ef /dev/slog
当我尝试打开从我的应用程序下载的 xls 文件时,出现此错误: excel cannot open the file because the file format or file extension
有一些相关的概念,即文件指针、流和文件描述符。 我知道文件指针是指向数据类型 FILE 的指针(在例如 FILE.h 和 struct_FILE.h 中声明)。 我知道文件描述符是 int ,例如成员
好吧,这应该很容易... 我是groovy的新手,我希望实现以下逻辑: def testFiles = findAllTestFiles(); 到目前为止,我想出了下面的代码,该代码可以成功打印所有文
我理解为什么以下内容会截断文件的内容: Get-Content | Out-File 这是因为 Out-File 首先运行,它会在 Get-Content 有机会读取文件之前清空文件。 但是当我尝
您好,我正在尝试将文件位置表示为变量,因为最终脚本将在另一台机器上运行。这是我尝试过的代码,然后是我得到的错误。在我看来,python 是如何添加“\”的,这就是导致问题的原因。如果是这种情况,我如何
我有一个只包含一行的输入文件: $ cat input foo bar 我想在我的脚本中使用这一行,据我所知有 3 种方法: line=$(cat input) line=$( input"...,
我是一名优秀的程序员,十分优秀!