我正在编写我的第一个客户端/服务器程序。客户端发送文件名,服务器应发送文件(如果存在)。 服务器:
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
变量,它没有,包含预期的值。谢谢你的回复!
答案 0 :(得分:0)
一切正常,直到客户端的while循环。 recv总是返回0。 那是为什么?
这意味着对等方已关闭连接。
我的代码出了什么问题?
您无法识别该情况,关闭套接字并停止尝试从中读取。这是recv()
返回0时必须执行的操作,或者实际返回-1时errno
等于EAGAIN/EWOULDBLOCK
以外的任何内容。
我试图通过一次发送向所需文件发送内容并收到它。我还检查了dataToRead变量,它没有,包含预期的值。
我看不出这与它有什么关系。
你的副本循环过于复杂。将字节从套接字传输到文件直到套接字上的流结束的规范方法如下:
while ((count = recv(socket, buffer, sizeof buffer)) > 0)
{
write(file, buffer, count);
}
反过来将字节从文件传输到套接字:
while ((count = read(file, buffer, sizeof buffer)) > 0)
{
send(socket, buffer, count);
}