-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathftpserver2.c
More file actions
131 lines (108 loc) · 3.25 KB
/
Copy pathftpserver2.c
File metadata and controls
131 lines (108 loc) · 3.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*************************************************************************
> File Name: serverWritev.c
> Author:
> Mail:
> Created Time: Sun 29 May 2016 11:47:03 AM CST
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/sendfile.h>
#include <sys/mman.h>
int main(int argc, char *argv[])
{
if(argc < 3){
printf("input: %s ip port", argv[0]);
return -1;
}
const char * ip = argv[1];
int port = atoi(argv[2]);
//创建socket
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
printf("socket error\n");
return -1;
}
//绑定socket和地址
//先填写地址
struct sockaddr_in servaddr;
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
inet_pton(AF_INET, ip, &servaddr.sin_addr);
servaddr.sin_port = htons(port);
//绑定地址
int ret = bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr));
if(ret != 0){
printf("bind error\n");
return -1;
}
//监听
ret = listen(sockfd, 5);
if(ret != 0){
printf("listen error\n");
return -1;
}
struct sockaddr_in clientaddr;
bzero(&clientaddr, sizeof(clientaddr));
socklen_t clientaddrLen;
//等待请求连接
while(1){
int connfd = accept(sockfd, (struct sockaddr*)&clientaddr, &clientaddrLen);
if(connfd < 0){
printf("accept error\n");
continue;
}
//如果accept成功,则将http的响应和要发送的文件的内容发送给客户端
char file_name[1024];
memset(file_name, 0, sizeof(file_name));
int num = read(connfd, file_name, sizeof(file_name));
if(num == 0){
printf("read error\n");
continue;
}
//获取文件的信息
struct stat file_stat;
ret = stat(file_name, &file_stat);
if(ret != 0){
printf("stat error\n");
}
//判断请求的是不是一个文件
if(S_ISDIR(file_stat.st_mode)){//如果是常规的文件
printf("请求的是目录,不是一个文件.\n");
close(connfd);
continue;
}
//打开文件
int filefd = open(file_name, O_RDONLY);
if(filefd < 0){
printf("open %s failed\n", file_name);
close(connfd);
continue;
}
/*
char filebuff[1024];
memset(filebuff, 0, 1024);
while((num = read(filefd, filebuff, sizeof(filebuff))) > 0){
write(connfd, filebuff, num);
//printf("write: %s\n", filebuff);
memset(filebuff, 0, 1024);
}
*/
//映射
char * file_buff = (char*)mmap(NULL, file_stat.st_size, PROT_READ, MAP_PRIVATE, filefd, 0);
//发送
write(connfd, file_buff, file_stat.st_size);
//解除映射
munmap(file_buff, file_stat.st_size);
printf("%s文件发送成功!\n", file_name);
close(filefd);
close(connfd);
}
return 0;
}