1 Star 0 Fork 2

sina_woker/文件传输系统

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
file_server.c 5.80 KB
一键复制 编辑 原始数据 按行查看 历史
jack-Huys 提交于 2020-05-17 20:07 . 源码
#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<errno.h>
#include<fcntl.h>
#include<unistd.h>
#include <dirent.h>
#include <time.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
#define port 8787
int sockfd;
int newfd;
struct sockaddr_in sockaddr;
struct sockaddr_in client_addr;
int sin_size;
SSL_CTX *ctx;//SSL套接字
SSL *ssl;
void f_time(){
time_t time1;
struct tm *t;//年月日时分秒的结构体定义一个结构体指针,localtime里面自有的
time(&time1);//获取到1900年的秒数
//time_t time(time_t *tloc);
// struct tm *localtime(const time_t *timep);
t = localtime( &time1);//获取当前时间
printf("%d-%d-%d %d:%d:%d\n", t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
}
void handle(char cmd){
char filename[30]={0};
int FileNameSize=0;
int fd;
int filesize=0;
int count=0,totalrecv=0;
char buf[1024];
struct stat fstat;
switch(cmd) {
case 'U':
{
//接收文件名
SSL_read(ssl, &FileNameSize, 4);
SSL_read(ssl, (void *)filename, FileNameSize);
filename[FileNameSize]='\0';
//创建文件
if((fd = open(filename,O_RDWR|O_CREAT)) == -1)
{
perror("creat:");
_exit(0);
}
//接收文件长度
SSL_read(ssl, &filesize, 4);
//接收文件
while((count = SSL_read(ssl,(void *)buf,1024)) > 0)
{
write(fd,&buf,count);
totalrecv += count;
if(totalrecv == filesize)
break;
}
printf("upload success\n");
system("ls");
//关闭文件
f_time();
close(fd);
}
break;
case 'D':
{
DIR *dirp;
struct dirent *dp;
dirp = opendir("."); //打开目录指针
while ((dp = readdir(dirp)) != NULL) { //通过目录指针读目录
printf("%s\n", dp->d_name );
}
closedir(dirp); //关闭目录
//接收文件名
SSL_read(ssl, &FileNameSize, 4);
SSL_read(ssl, filename, FileNameSize);
filename[FileNameSize]='\0';
//打开文件
if((fd = open(filename,O_RDONLY)) == -1)
{
perror("creat:");
_exit(0);
}
//发送文件包括文件长度
if((stat(filename,&fstat)) == -1)
return;
SSL_write(ssl,&fstat.st_size,4);
while((count = read(fd,(void *)buf,1024)) > 0)
{
SSL_write(ssl,&buf,count);
}
printf("download success\n");
f_time();
close(fd);
}
break;
}
}
int main(){
int ret;
char cmd;
//建立连接
//ssl连接
//初始化ssl
SSL_library_init();
OpenSSL_add_all_algorithms();
SSL_load_error_strings();
ctx = SSL_CTX_new(SSLv23_server_method());//创建ssl套接字参数表明支持版本和客户机
//载入数字证书
SSL_CTX_use_certificate_file(ctx,"./cacert.pem",SSL_FILETYPE_PEM);
//载入并检查私钥
SSL_CTX_use_PrivateKey_file(ctx,"./privkey.pem",SSL_FILETYPE_PEM);
SSL_CTX_check_private_key(ctx);
//创建socket
if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
{
perror("socket:");
_exit(0);
}
memset(&sockaddr,0, sizeof(sockaddr));
// 配置listen_fd的TIME_WAIT时可复用
//bind 普遍遭遇的问题是试图绑定一个已经在使用的端口。
// 该陷阱是也许没有活动的套接字存在,但仍然禁止绑定端口(bind 返回 EADDRINUSE),它由 TCP 套接字状态 TIME_WAIT 引起。
// 该状态在套接字关闭后约保留 2 到 4 分钟。在 TIME_WAIT 状态退出之后,套接字被删除,该地址才能被重新绑定而不出问题。
int on = 1;
ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
if ( ret == -1 ) {
perror("set sock reuse addr:");
return -1;
}
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons(port);
sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
//绑定地址
if(bind(sockfd,(struct sockaddr *)&sockaddr,sizeof(sockaddr)) == -1)
{
perror("bind:");
_exit(0);
}
//监听
if(listen(sockfd,10) == -1) {
perror("listen");
}
printf("listen...........\n");
while(1)
{
//连接
if((newfd = accept(sockfd, (struct sockaddr *)(&client_addr),&sin_size)) == -1)
{
perror("accept:");
_exit(0);
}
ssl = SSL_new(ctx);//产生新的ssl
SSL_set_fd(ssl,newfd);//newfd放进ssl
SSL_accept(ssl);//ssl连接
//处理事件
printf("连接成功\n");
f_time();
while(1)
{
SSL_read(ssl,&cmd,1);
if(cmd == 'Q')
{
printf("拜拜了您\n");
f_time();
break;
}
else
{
handle(cmd);
}
}
SSL_shutdown(ssl);
SSL_free(ssl);
close(newfd);
}
close(sockfd);
SSL_CTX_free(ctx);
return 0;
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C
1
https://gitee.com/lin-binghua/file_transfer_system.git
[email protected]:lin-binghua/file_transfer_system.git
lin-binghua
file_transfer_system
文件传输系统
master

搜索帮助