利用socket实现云盘的:
ls 查看服务端文件
lls 查看客户端文件
cd 切换服务端目录
lcd 切换客户端目录
put 上传文件
get 下载文件
服务端代码:
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include<pthread.h>
#include<unistd.h>
#include<semaphore.h>
#include<sys/stat.h>
#include<fcntl.h>
void *myfun1(void *arg)
{
int clientid;
clientid=*(int *)arg;
int ret;
int sfd=dup(1);
char buf[128];
while(1)
{
ret=read(clientid,buf,128);
printf("ret====%d,buf=======%s\n",ret,buf);
if(strcmp("ls",buf)==0)
{
dup2(clientid,1);
system("ls");
dup2(sfd,1);
}
else if(strncmp("cd",buf,2)==0)
{
char *p=buf;
p=p+3;
chdir(p);
}
else if(strncmp("put",buf,3)==0)
{
char *p=buf;
p=p+4;
int fd;
fd=open(p,O_CREAT|O_RDWR,0755);
char sbuf[8000]={0};
ret=read(clientid,sbuf,8000);
write(fd,sbuf,strlen(sbuf));
printf("put ok\n");
close(fd);
}
else if(strncmp("get",buf,3)==0)
{
char *p=buf;
p=p+4;
ret=access(p,F_OK);
if(ret==-1)
{
char dbuf[]="file not access";
write(clientid,dbuf,strlen(dbuf));
}
else
{
write(clientid,buf,strlen(buf));
int fd;
fd=open(p,O_RDONLY);
char sbuf[8000]={0};
ret=read(fd,sbuf,8000);
write(clientid,sbuf,ret);
printf("get ok\n");
close(fd);
}
}
memset(buf,0,128);
}
}
int main(int argc,char *argv[])
{
if(argc<3)
{
printf("argc fail\n");
exit(1);
}
int fd;
fd=socket(AF_INET,SOCK_STREAM,0);
if(fd==-1)
{
perror("socket fail");
exit(1);
}
struct sockaddr_in serveraddr;
bzero(&serveraddr,sizeof(serveraddr));
serveraddr.sin_family=AF_INET;
serveraddr.sin_port=htons(atoi(argv[2]));
serveraddr.sin_addr.s_addr=inet_addr(argv[1]);
int ret;
ret=bind(fd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));
if(ret==-1)
{
perror("bind fail");
exit(1);
}
ret=listen(fd,5);
if(ret==-1)
{
perror("listen fail");
exit(1);
}
struct sockaddr_in clientaddr;
bzero(&clientaddr,sizeof(clientaddr));
socklen_t len=sizeof(clientaddr);
int clientid;
pthread_t pthid1;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
while(1)
{
clientid=accept(fd,(struct sockaddr *)&clientaddr,&len);
if(clientid==-1)
{
perror("accept fail");
exit(1);
}
printf("ip:%s,port:%d\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));
pthread_create(&pthid1,&attr,myfun1,(void *)&clientid);
}
pthread_attr_destroy(&attr);
close(fd);
return 0;
}
客户端代码:
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<string.h>
#include<pthread.h>
#include<unistd.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/stat.h>
#include<fcntl.h>
void *myfun1(void *arg)
{
int fd;
int ret;
fd=*(int *)arg;
char buf[128];
while(1)
{
fgets(buf,128,stdin);
ret=strlen(buf);
buf[ret-1]='\0';
if(strncmp("ls",buf,2)==0)
{
write(fd,buf,strlen(buf));
char sbuf[8000]={0};
ret=read(fd,sbuf,8000);
printf("%s\n",sbuf);
}
else if(strncmp("lls",buf,3)==0)
{
system("ls");
}
else if(strncmp("cd",buf,2)==0)
{
write(fd,buf,strlen(buf));
}
else if(strncmp("lcd",buf,3)==0)
{
char *p=buf;
p=p+4;
chdir(p);
}
else if(strncmp("put",buf,3)==0)
{
char *p=buf;
p=p+4;
ret=access(p,F_OK);
if(ret==-1)
{
printf("file no access\n");
}
else
{
write(fd,buf,strlen(buf));
int fd1;
fd1=open(p,O_RDONLY);
char sbuf[8000]={0};
ret=read(fd1,sbuf,8000);
write(fd,sbuf,strlen(sbuf));
close(fd1);
}
}
else if(strncmp("get",buf,3)==0)
{
char *p=buf;
p=p+4;
int fd1;
write(fd,buf,strlen(buf));
char dbuf[128]={0};
ret=read(fd,dbuf,128);
if(strncmp("file",dbuf,4)==0)
{
printf("%s\n",dbuf);
}
else
{
fd1=open(p,O_CREAT|O_RDWR,0766);
char sbuf[8000]={0};
ret=read(fd,sbuf,8000);
write(fd1,sbuf,ret);
close(fd1);
}
}
memset(buf,0,128);
}
}
int main(int argc,char *argv[])
{
if(argc<3)
{
printf("argc fail\n");
exit(1);
}
int fd;
fd=socket(AF_INET,SOCK_STREAM,0);
if(fd==-1)
{
perror("socket fail");
exit(1);
}
struct sockaddr_in serveraddr;
bzero(&serveraddr,sizeof(serveraddr));
serveraddr.sin_family=AF_INET;
serveraddr.sin_port=htons(atoi(argv[2]));
serveraddr.sin_addr.s_addr=inet_addr(argv[1]);
int ret;
ret=connect(fd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));
if(ret==-1)
{
perror("connect fail");
exit(1);
}
printf("connect success\n");
pthread_t pthid1;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
pthread_create(&pthid1,&attr,myfun1,(void *)&fd);
while(1);
pthread_attr_destroy(&attr);
close(fd);
}
运行结果:
服务端是TCP并发服务器,可以同时被多个客户端访问。
服务端TCP并发服务器是采用多线程实现的,在服务端代码中每一个客户端都开辟一个线程去处理。每一个线程是分离态,以便线程结束自动释放资源。
服务端ls功能是 通过重定向dup2结合system实现的。