1.文件服务器
2.实现文件的上传下载,模拟百度云。
直接看代码吧:
client端
//client.c
include “Dclient.h”
include “Fclient.h”
include “Debug.h”
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include “type.h”
include
include “Debug.h”
sqlite3 *db = NULL;
pthread_mutex_t list_lock;
void *wait_for_iprequest(void *x)
{
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(-1 == sockfd)
{
perror(“socket”);
return NULL;
}
struct sockaddr_in serveraddr = {0}, clientaddr;
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = INADDR_ANY;//inet_addr("0.0.0.0");
serveraddr.sin_port = htons(DATABASEPORT);
int len = sizeof serveraddr;
int on = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on , sizeof on);
if(-1 == bind(sockfd, (struct sockaddr*)&serveraddr, len) )
{
perror("bind");
return NULL;
}
char buf[BUFSIZE] = {0};
while(1)
{
recvfrom(sockfd, buf, sizeof buf, 0, (struct sockaddr*)&clientaddr, &len);
sendto(sockfd, buf, sizeof buf, 0, (struct sockaddr*)&clientaddr, len);
}
}
void *func(void *arg)
{
int clientfd = (int)arg;
while(1)
{
char buf[BUFSIZE] = {0};
int ret = read(clientfd, buf, BUFSIZE);
if(0 == ret || -1 == ret)
break;
if(0 == strncmp("register", buf, 8) )
{
char name[20] = {0};
char pass[20] = {0};
sscanf(buf, "%*s%s%s", name, pass);
pthread_mutex_lock(&list_lock);
char sql[BUFSIZE] = {0};
sprintf(sql, "insert into userpass values('%s', '%s');", name, pass);
char *errmsg;
if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
printf("error : %s\n", errmsg);
exit(-1);
}
bzero(sql, BUFSIZE);
sprintf(sql, "create table %s(filename);", name);
if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
printf("error : %s\n", errmsg);
exit(-1);
}
pthread_mutex_unlock(&list_lock);
strcpy(buf, "ok");
write(clientfd, buf, sizeof buf);
}
else
if(0 == strncmp("changepass", buf, 10) )
{
char name[20] = {0};
char pass[20] = {0};
char newpass[20] = {0};
char sql[BUFSIZE] = {0};
sscanf(buf, "%*s%s%s%s", name, pass, newpass);
pthread_mutex_lock(&list_lock);
bzero(sql, BUFSIZE);
sprintf(sql, "update userpass set pass='%s' where name='%s' and pass='%s';",newpass, name, pass);
char *errmsg;
if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
printf("error : %s\n", errmsg);
exit(-1);
}
pthread_mutex_unlock(&list_lock);
strcpy(buf, "ok");
write(clientfd, buf, sizeof buf);
}
else
if(0 == strncmp("login", buf, 5) )
{
char name[20] = {0};
char pass[20] = {0};
sscanf(buf, "%*s%s%s", name, pass);
pthread_mutex_lock(&list_lock);
char sql[BUFSIZE] = {0};
sprintf(sql, "select * from userpass where name='%s' and pass='%s';", name, pass);
char *errmsg,**resultp;
int nrow, ncolumn, i, j, index;
if(sqlite3_get_table(db, sql, &resultp, &nrow, &ncolumn, &errmsg) != SQLITE_OK)
{
printf("error : %s\n", errmsg);
exit(-1);
}
pthread_mutex_unlock(&list_lock);
strcpy(buf, nrow!=0?"OK":"no");
write(clientfd, buf, sizeof buf);
}
else
if(0 == strncmp("requestlist", buf, 11) )
{
char name[20] = {0};
sscanf(buf, "%*s%s", name);
char sql[BUFSIZE] = {0};
sprintf(sql, "select * from %s;", name);
char *errmsg,**resultp;
int nrow, ncolumn, i, j, index;
if(sqlite3_get_table(db, sql, &resultp, &nrow, &ncolumn, &errmsg) != SQLITE_OK)
// {
// printf(“error : %s\n”, errmsg);
// exit(-1);
// }
bzero(buf, BUFSIZE);
i = 1;
for(;i<=nrow; i++)
{
strcat(strcat(buf, resultp[i]), " ");
}
write(clientfd, buf, sizeof buf);
}
else
if(0 == strncmp("adduserfile", buf, 11) )
{
char username[20] = {0};
char filename[20] = {0};
sscanf(buf, "%*s%s%s", username, filename);
char sql[BUFSIZE] = {0};
sprintf(sql, "insert into %s values('%s');", username, filename);
char *errmsg;
if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
printf("error : %s\n", errmsg);
exit(-1);
}
strcpy(buf, "OK");
write(clientfd, buf, sizeof buf);
}
else
strcpy(buf, "cmd err!\n");
}
}
extern void wait_for_iprequest(void);
int main(int argc, char *argv[])
{
if(SQLITE_OK != sqlite3_open("my.db", &db) )
{
printf("%s\n", sqlite3_errmsg(db));
return -1;
}
//create userpass table
char *errmsg;
if(sqlite3_exec(db, "create table userpass('name', 'pass');", NULL, NULL, &errmsg) != SQLITE_OK);
int pid = fork();
//子进程接收广播,父进程服务
if(0 == pid)
{
wait_for_iprequest(NULL);
}
else
{
int fd = socket(AF_INET, SOCK_STREAM, 0);//申请网络服务,获得套接字文件描述符fd
if(-1 == fd)
{
perror("socket");
return -1;
}
struct sockaddr_in serveraddr = {0}, clientaddr = {0};//准备好服务器的地址及端口描述
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr("0.0.0.0");
serveraddr.sin_port = htons(8888);//服务器软件绑定的端口
int len = sizeof serveraddr;
//set reuse
int on = 1;
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on);
if(-1 == bind(fd, (struct sockaddr*)&serveraddr, len) )
{
perror("connect");
return -1;
}
listen(fd, 10);//start wait
pthread_mutex_init(&list_lock, NULL);
while(1)
{
printf("waiting............\n");
int clientfd = accept(fd, (struct sockaddr*)&clientaddr, &len);
printf("incoming: %s\n", inet_ntoa(clientaddr.sin_addr) );
pthread_t t;
pthread_create(&t, NULL, func, (void*)clientfd);
}
}
}
//Fserver.c
include
include
include
include
include
include
include
include
include
include
include
include “Dclient.h”
include “type.h”
include “Debug.h”
include
ifndef DC
define DC
include “type.h”
typedef struct Dclient{
char IP[MAXLEN];
char username[MAXLEN];
}DC;
DC *open_Dclient(void);
//for client
int register_Dclient(DC *dc, const char *username, const char *passwd);
int login_Dclient(DC *dc, const char *username, const char *passwd);
int changepass_Dclient(DC *dc, const char *username, const char *passwd, const char *newpasswd);
//for Fserver
int requestlist_Dclient(DC *dc, const char *username, char *listbuf);
int adduserfile_Dclient(DC *dc, const char *username, const char *filename);
endif
//Debug.h
ifndef DEBUG
define DEBUG
include
ifdef DEBUG
#define Debug(format, args...) printf(format, ##args)
else
#define Debug(format, args...)
endif
endif
//Fclient.h
ifndef FC
define FC
include “type.h”
typedef struct Fclient{
int sockfd;
}FC;
//for client
FC *open_Fclient();
int putfile_Fclient(FC *fd, const char *username, const char *filename);
int getfile_Fclient(FC *fd, const char *username, const char *filename);
int listfile_Fclient(FC *fd, const char *username, char *listbuf);
endif
//type.h
ifndef TYPE_
define TYPE_
define MAXLEN 20
define BUFSIZE 1024
define DATABASEPORT 8888
define FILESERVERPORT 9999
endif
//Dclient.c
include “Dclient.h”
include
include
include
include
include
include
include
include
include “Debug.h”
DC *open_Dclient(void)
{
char serverIP[20] = {0};
DC *dc = malloc(sizeof(DC));
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(-1 == sockfd)
{
perror("socket");
return NULL;
}
struct sockaddr_in serveraddr = {0};
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr("255.255.255.255");
serveraddr.sin_port = htons(DATABASEPORT);
int len = sizeof serveraddr;
int on = 1;
setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof on);
struct timeval t = {5};
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &t, sizeof t);
char buf[] = {"database"};
while(1)
{
sendto(sockfd, buf, sizeof buf, 0, (struct sockaddr*)&serveraddr, len);
if(-1 == recvfrom(sockfd, buf, sizeof buf, 0, (struct sockaddr*)&serveraddr, &len) )
{
printf("database server not ready!\n");
return NULL;
}
else
{
strcpy(serverIP, inet_ntoa(serveraddr.sin_addr));
break;
}
}
strcpy(dc->IP, serverIP);
return dc;
}
static int connect_server(DC *dc)
{
int sockfd = socket(AF_INET, SOCK_STREAM, 0);//申请网络服务,获得套接字文件描述符fd
if(-1 == sockfd)
{
perror(“socket”);
return -1;
}
struct sockaddr_in serveraddr = {0};//准备好服务器的地址及端口描述
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr(dc->IP);//服务器IP地址
serveraddr.sin_port = htons(DATABASEPORT);//服务器软件绑定的端口
int len = sizeof serveraddr;
if(-1 == connect(sockfd, (struct sockaddr*)&serveraddr, len) )//连接服务器测试线路状态
{
perror("connect");
return -1;
}
return sockfd;
}
//for client
int register_Dclient(DC *dc, const char *username, const char *passwd)
{
int sockfd = connect_server(dc);
if(-1 == sockfd)
return -1;
char buf[BUFSIZE] = {0};
sprintf(buf, "%s %s %s", "register", username, passwd);
write(sockfd, buf, sizeof buf);
read(sockfd, buf, sizeof buf);
if(0 == strcmp("OK", buf) )
return 0;
else
return -1;
}
int login_Dclient(DC *dc, const char *username, const char *passwd)
{
int sockfd = connect_server(dc);
if(-1 == sockfd)
return -1;
char buf[BUFSIZE] = {0};
sprintf(buf, "%s %s %s", "login", username, passwd);
write(sockfd, buf, sizeof buf);
read(sockfd, buf, sizeof buf);
if(0 == strncmp("OK", buf, 2) )
return 0;
else
return -1;
}
int changepass_Dclient(DC *dc, const char *username, const char *passwd, const char *newpasswd)
{
int sockfd = connect_server(dc);
if(-1 == sockfd)
return -1;
char buf[BUFSIZE] = {0};
sprintf(buf, "%s %s %s %s", "changepass", username, passwd, newpasswd);
write(sockfd, buf, sizeof buf);
read(sockfd, buf, sizeof buf);
if(0 == strcmp("OK", buf) )
return 0;
else
return -1;
}
//for Fserver
int requestlist_Dclient(DC *dc, const char *username, char *listbuf)
{
int sockfd = connect_server(dc);
if(-1 == sockfd)
return -1;
char buf[BUFSIZE] = {0};
sprintf(buf, "%s %s", "requestlist", username);
write(sockfd, buf, sizeof buf);
read(sockfd, listbuf, sizeof buf);
return 0;
}
int adduserfile_Dclient(DC *dc, const char *username, const char *filename)
{
int sockfd = connect_server(dc);
if(-1 == sockfd)
return -1;
char buf[BUFSIZE] = {0};
sprintf(buf, "%s %s %s", "adduserfile", username, filename);
write(sockfd, buf, sizeof buf);
read(sockfd, buf, sizeof buf);
if(0 == strcmp("OK", buf) )
return 0;
else
return -1;
}
//Fclient.c
include “Fclient.h”
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include “Debug.h”
//for client
FC *open_Fclient()
{
char FILESERVERIP[MAXLEN] = {0};
FC *fc = malloc(sizeof(FC));
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(-1 == sockfd)
{
perror("socket");
return NULL;
}
struct sockaddr_in serveraddr = {0};
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr("255.255.255.255");
serveraddr.sin_port = htons(FILESERVERPORT);
int len = sizeof serveraddr;
int on = 1;
setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof on);
struct timeval t = {5};
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &t, sizeof t);
char buf[] = {"fileserver"};
while(1)
{
sendto(sockfd, buf, sizeof buf, 0, (struct sockaddr*)&serveraddr, len);
if(-1 == recvfrom(sockfd, buf, sizeof buf, 0, (struct sockaddr*)&serveraddr, &len) )
{
printf("file server not ready!\n");
return NULL;
}
else
{
strcpy(FILESERVERIP, inet_ntoa(serveraddr.sin_addr));
break;
}
}
int Tcpsockfd = socket(AF_INET, SOCK_STREAM, 0);//申请网络服务,获得套接字文件描述符fd
if(-1 == Tcpsockfd)
{
perror("socket");
return NULL;
}
struct sockaddr_in Tserveraddr = {0};//准备好服务器的地址及端口描述
Tserveraddr.sin_family = AF_INET;
Tserveraddr.sin_addr.s_addr = inet_addr(FILESERVERIP);//服务器IP地址
Tserveraddr.sin_port = htons(FILESERVERPORT);//服务器软件绑定的端口
len = sizeof Tserveraddr;
if(-1 == connect(Tcpsockfd, (struct sockaddr*)&Tserveraddr, len) )//连接服务器测试线路状态
{
perror("connect");
return NULL;
}
fc->sockfd = Tcpsockfd;
return fc;
}
int putfile_Fclient(FC *fc, const char *username, const char *filename)
{
char buf[BUFSIZE] = {0};
sprintf(buf, “%s %s %s”, “put”, filename, username);
//send file put request
int ret = write(fc->sockfd, buf, sizeof buf);
//send file size
struct stat s;
ret = stat(filename, &s);
sprintf(buf, “%ld”, s.st_size);
ret = write(fc->sockfd, buf, sizeof buf);
//send file data
int fdx = open(filename, O_RDONLY);
int n = 0;
while(n = read(fdx, buf, sizeof buf) )
{
ret = write(fc->sockfd, buf, n);
}
printf("成功上传 %s 文件!\n",filename);
close(fdx);
}
int getfile_Fclient(FC *fc, const char *username, const char *filename)
{
char buf[BUFSIZE] = {0};
sprintf(buf, “%s %s %s”, “get”, filename, username);
//send get request
write(fc->sockfd, buf, sizeof buf);
//recv file stat
read(fc->sockfd, buf, sizeof buf);
//if NO, continue;
if(0 == strncmp(“NO”, buf, 2) )
{
printf(“No such file on server !\n”);
return -1;
}
//if OK, recv file size
read(fc->sockfd, buf, sizeof buf);
int size = atoi(buf);
int filesize=size;
//read file data && save into a new file
int fd = open(filename, O_CREAT|O_TRUNC|O_WRONLY, 0666);
while(size)
{
//read data
int n = read(fc->sockfd, buf, sizeof buf);
//save data
write(fd, buf, n);
size -= n;
}
printf("下载了一个文件!\n");
printf("文件大小为:%dByte\n", filesize);
close(fd);
}
int listfile_Fclient(FC *fc, const char *username, char *listbuf)
{
char buf[BUFSIZE] = {0};
sprintf(buf, “%s %s”, “list”, username);
//send get request
write(fc->sockfd, buf, sizeof buf);
read(fc->sockfd, listbuf, sizeof buf);
// printf(“%s\n”, buf);
return 0;
}