我编写了一个简单的服务器来将文件传输到客户端。以下是源代码。
//server.c
#include "general.h"
#define LISTENQ 10
#define BUFSIZE 1024
#define FILENAME "List"
void sendlist(int sockfd) {
int fd = open(FILENAME, O_RDONLY);
char readbuf[BUFSIZE];
ssize_t n;
if(fd == -1)
exit(1);
for(;;) {
if((n = read(fd, readbuf, BUFSIZE)) > 0)
write(sockfd, readbuf, BUFSIZE);
else
break;
}
close(fd);
close(sockfd);
}
int main(int argc, char ** argv) {
int listenfd, connfd;
pid_t childpid;
socklen_t len;
struct sockaddr_in cliaddr, servaddr;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
bind(listenfd, (struct sockaddr_in *)&servaddr, sizeof(servaddr));
listen(listenfd,LISTENQ);
for(;;) {
len = sizeof(cliaddr);
connfd = accept(listenfd, (struct sockaddr_in *)&cliaddr, &len);
if((childpid = fork()) == 0) {
close(listenfd);
sendlist(connfd);
exit(0);
}
close(connfd);
}
}
//client.c
#include "general.h"
#define MAXLINE 1024
#define FILENAME "List2"
void getlist(int sockfd) {
int fd = creat(FILENAME, S_IRUSR | S_IWUSR);
char buf[MAXLINE];
ssize_t n;
if(fd == -1)
exit(2);
for(;;) {
if((n = read(sockfd, buf, MAXLINE)) > 0)
write(fd, buf, MAXLINE);
else
break;
}
close(fd);
}
int main(int argc, char ** argv) {
int sockfd;
struct sockaddr_in servaddr;
if(argc != 2)
exit(1);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
connect(sockfd, (struct sockaddr_in *)&servaddr, sizeof(servaddr));
getlist(sockfd);
exit(0);
}
我的问题是:文件List和List2不一样。
例如,文件列表的内容为:test
文件List2的内容不仅包含test
,还包含许多不可读的代码:
^@^@^@^@^@^@^@^@^@<8c>]úUü^?^@^@ ^G^\Vü^?^@^@^A^@^@^
我认为原因是读写功能。我不应该使用它们吗? 感谢
答案 0 :(得分:4)
您正在将整个缓冲区写入文件,而只有第一个n
字节有效。替换:
for(;;) {
if((n = read(sockfd, buf, MAXLINE)) > 0)
write(fd, buf, MAXLINE);
使用:
for(;;) {
if((n = read(sockfd, buf, MAXLINE)) > 0)
write(fd, buf, n);
所有相似的事件都相应地发生。
答案 1 :(得分:1)
喜欢
for(;;) {
memset(readbuf , 0, BUFSIZE); // Clear Memory here
if((n = read(fd, readbuf, BUFSIZE)) > 0)
write(sockfd, readbuf, n); // Send what you read
else
break;
}
// similarly While reading
for(;;) {
memset(buf , 0 , MAXLINE); // again do a memset
if((n = read(sockfd, buf, MAXLINE)) > 0)
write(fd, buf, n); // Write What you read
else
break;
}
答案 2 :(得分:0)
Read()和write()可以执行部分读/写。这由返回值表示,它是成功传输的字节数,可以与给予它们的第3个参数不同。
while(1) {
int n;
unsigned todo, done;
n = read(fd, readbuf, BUFSIZE);
if (n <= 0) break;
for(todo=n,done=0; done < todo; done += n ) {
n = write(sockfd, readbuf+done, todo - done);
if (n <= 0) return FAILURE;
}
}