C socket recv函数返回未定义错误(errno)

问题描述 投票:0回答:1

我正在尝试制作文件传输程序。我目前正在对C服务器进行编程,并使用简短的Python脚本作为客户端。当我尝试将文件名从Python发送到C时,recv函数(在C中)返回未定义的错误。它一次收到文件名的一半。这是代码:C服务器(指出recv功能有问题):



#define BUFFER 2000000
#define HEADERSIZE 20
#define PORT 9342
#define FGET "FGET"
#define UPLD "UPLD"

typedef struct timeval timeval_t;

int i;
fd_set readlist, sockets;

void* sendf(void* sock){
  printf("File Descriptor: %d\n", *(int*)sock);
  fflush(stdout);
  char* filename = (char*) malloc(21*sizeof(char));
  ssize_t result = recv(*(int*)sock, filename, 20+1, 0);
  if (result != 0){
    printf("%s", strerror(errno));
    exit(0);
  }
  printf("Filename: ");
  puts(filename);
  FILE* sfile = fopen(filename, "rb");
  free(filename);
  fseek(sfile, 0, SEEK_END);
  unsigned long long filesize = ftell(sfile);
  fseek(sfile, 0, SEEK_SET);
  char* content = malloc(BUFFER);
  for(i=0; i<=ceil(filesize/BUFFER); ++i){
    if (filesize >= BUFFER){
      fread(content, BUFFER, 1, sfile);
      filesize-=BUFFER;
      fseek(sfile, filesize-1, SEEK_END);
    } else{
      fread(content, filesize, 1, sfile);
    }
    content = realloc(content, BUFFER);
  }
  fclose(sfile);
  char* header = malloc(HEADERSIZE);
  sprintf(header, "%20llu", filesize);
  send(*(int*)sock, header, 20, 0);
  send(*(int*)sock, content, filesize, 0);
  free(filename);
  free(content);
  free(header);
  return NULL;
}

void* receivef(void* sock){
  printf("Function not written yet");
  return NULL;
}

int main(){

  chdir("/Users/reimeytal/Desktop/Fileserver");
  int sock = socket(AF_INET, SOCK_STREAM, 0);
  pthread_t thread;
  timeval_t timeout;
  timeout.tv_sec = 1;
  timeout.tv_usec = 0;
  struct sockaddr_in server;
  server.sin_port = htons(PORT);
  server.sin_addr.s_addr = INADDR_ANY;
  server.sin_family = AF_INET;
  FD_ZERO(&sockets);
  FD_SET(sock, &sockets);
  bind(sock, (struct sockaddr*)&server, sizeof(server));
  listen(sock, 5);
  int maxsock = sock;
  int clientsock;
  char* msghdr = (char*) malloc(5*sizeof(char));
  while (1){
    readlist = sockets;
    select(FD_SETSIZE, &readlist, NULL, NULL, &timeout);
    for(i=0; i<=maxsock; i++){
      if(FD_ISSET(i, &readlist)){
        if(i==sock){
          clientsock = accept(sock, NULL, NULL);
          FD_SET(clientsock, &sockets);
          if(clientsock>sock){
            maxsock = clientsock;
          }
        } else{
          printf("Incoming message from %d\n", i);
          fflush(stdout);
          recv(i, msghdr, 5, 0);
          clientsock = i;
          if(strcmp(msghdr, FGET) == 0){
            pthread_create(&thread, NULL, sendf, (int *)&clientsock);
          }/*else if(strcmp(msghdr, UPLD) == 0){
            pthread_create(&thread, NULL, receivef, (int*)&i);
          }else{
            puts("ERROR: Received invalid message header");
          }*/
          msghdr = (char *) realloc(msghdr, 5*sizeof(char));
        }
      }
    }
  }
  return 0;

运行时的结果:

Incoming message from 4
File Descriptor: 4
Incoming message from 4
Incoming message from 4
Undefined error: 0

Python客户端:

import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("localhost", 9342))
sock.send(b'FGET\0')
sock.send(b'abcdeftghijklmno.txt\0')

[如果有人需要我澄清/添加一些内容,我很乐意这样做。谢谢

python c sockets errno
1个回答
0
投票

有一些错误,第一个:

ssize_t result = recv(*(int*)sock, filename, 20+1, 0);
  if (result != 0){
    printf("%s", strerror(errno));
    exit(0);
  }

recv返回写入的字节数,因此应检查if (result <= 0)

在您的情况下,recv返回0,从技术上讲这不是错误代码,它仅表示另一端的套接字关闭了连接。 (这就是为什么您会得到未定义的错误的原因。)

那么为什么另一个插座关闭?好吧,因为您的Python脚本可能已在服务器读取您的消息时结束。在最后一次sock.send调用之后,Python程序完成,清除其所有资源(包括套接字)并终止。然后关闭套接字。

这是一个时间问题:如果您很幸运,Python程序尚未清理其资源,服务器有足够的时间读取答复。这也解释了为什么它适用于@wierzmar。

[要修复它,请等待确认消息(可以从服务器发送),然后在Python端接收。或者只是在Python脚本的末尾添加sleep(10)-不太好,但是如果您只是测试一些东西,它就可以使用。

© www.soinside.com 2019 - 2024. All rights reserved.