我正在编写我的第一个客户端/服务器程序。客户端发送文件名,服务器应发送该文件(如果存在)。 服务器:
while(1)
{
client_sock_fd = accept(listening_sock_fd, (struct sockaddr*)NULL, NULL);
if (client_sock_fd == -1)
{
fprintf(stderr, "ERROR: accept()\n");
continue;
}
if (!fork())
{
close(listening_sock_fd);
if ((numbytes = recv(client_sock_fd, buff, 1023, 0)) == -1){
fprintf(stderr, "ERROR: recv()\n");
return EXIT_FAILURE;
}
buff[numbytes] = '\0';
FILE *f = fopen(buff, "r");
if (f == NULL){
if ((send(client_sock_fd, "FAIL", 4, 0)) == -1)
{
fprintf(stderr, "ERROR: send()\n");
}
}else {
if ((send(client_sock_fd, "OK", 2, 0)) == -1)
{
fprintf(stderr, "ERROR: send()\n");
}
char * buffer = 0;
long length;
fseek (f, 0, SEEK_END);
length = ftell (f);
fseek (f, 0, SEEK_SET);
if((buffer = malloc (length)) == NULL){
fprintf(stderr, "ERROR: malloc()\n");
exit(1);
}
if (buffer)
{
fread (buffer, 1, length, f);
}
fclose (f);
char str[1024];
sprintf(str, "%d", (int)strlen(buffer));
if ((send(client_sock_fd, str, strlen(str), 0)) == -1)
{
fprintf(stderr, "ERROR: send()\n");
}
int s = sendall(client_sock_fd, buffer, strlen(buffer));
if (s == -1){
fprintf(stderr, "ERROR: send()\n");
free(buffer);
exit(1);
}
free(buffer);
}
close(client_sock_fd);
exit(0);
}
close(client_sock_fd);
}
int sendall(int s, char *buf, int len)
{
int total = 0;
int bytesleft = len;
int n;
while(total < len) {
n = send(s, buf+total, bytesleft, 0);
if (n == -1) { break; }
total += n;
bytesleft -= n;
}
return n==-1?-1:0;
}
客户:
if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
fprintf(stderr, "ERROR: chyba pri socket()\n");
return EXIT_FAILURE;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(args.port_num);
if ((prlHst = gethostbyname(argv[args.host_name])) == NULL){
fprintf(stderr, "ERROR: gethostbyname()\n");
return EXIT_FAILURE;
}
memcpy(&serv_addr.sin_addr, prlHst->h_addr_list[0], prlHst->h_length);
if (connect(sock_fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0){
fprintf(stderr, "ERROR: connect()\n");
return EXIT_FAILURE;
if ((send(sock_fd, argv[args.file], strlen(argv[args.file]), 0)) == -1){
fprintf(stderr, "ERROR: send()\n");
return EXIT_FAILURE;
}
if ((numbytes = recv(sock_fd, buff, 1023, 0)) == -1){
fprintf(stderr, "ERROR: recv()\n");
return EXIT_FAILURE;
}
buff[numbytes] = '\0';
FILE *fp = fopen(argv[args.file], "w");
if (fp == NULL){
fprintf(stderr, "ERROR: fopen()\n");
return EXIT_FAILURE;
}
if (!strcmp(buff, "OK")){
if ((numbytes = recv(sock_fd, buff, 1023, 0)) == -1){
fprintf(stderr, "ERROR: recv()\n");
return EXIT_FAILURE;
}
char *pEnd;
long int dataToRead = strtol(buff, &pEnd, 10);
long int readData = 0;
fprintf(stderr, "data to read %lu\n", dataToRead);
while (readData < dataToRead) {
unsigned char buffer [4096] = {0};
int nbuffer;
for (nbuffer = 0; nbuffer < 4096; ) {
int len = recv(sock_fd, buffer, 4096, 0);
if (len == -1){
fprintf(stderr, "ERROR: recv()\n");
return EXIT_FAILURE;
}
/* FIXME: Error checking */
nbuffer += len;
readData += len;
}
fwrite(buffer, sizeof(unsigned char), nbuffer, fp);
}
一切正常,直到客户端中的 while 循环为止。 recv
始终返回 0
。这是为什么?我的代码有什么问题吗?我尝试用一次send
向所需的文件写入一些内容,并且它被接收了。我还检查了 dataToRead 变量,它没问题,包含预期值。感谢您的回复!
最佳答案
Everything works fine until the while loop in client. recv always returns 0. Why is that?
这意味着对端已关闭连接。
What's wrong in my code?
您没有识别出这种情况,没有关闭套接字,也没有停止尝试从中读取数据。这是当 recv()
返回 0 时,或者实际上当它返回 -1 且 errno
等于除 EAGAIN/EWOULDBLOCK
之外的任何值时必须执行的操作.
I tried to write something to the wanted file send with one send and it was received. Also I checked dataToRead variable and it's ok, containing the expected value.
我不明白这有什么关系。
你的复制循环过于复杂。将字节从套接字传输到文件直到套接字上的流结束的规范方法如下:
while ((count = recv(socket, buffer, sizeof buffer)) > 0)
{
write(file, buffer, count);
}
反之,将字节从文件传输到套接字:
while ((count = read(file, buffer, sizeof buffer)) > 0)
{
send(socket, buffer, count);
}
关于c - 没有接收到数据,recv()返回0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36738073/