TCP/UDP文件传输与并发服务器
#include <myhead.h> #define SER_IP "192.168.125.78" #define SER_PORT 69 #define CLI_IP "192.168.125.176" #define CLI_PORT 4399 //文件上传 void upload(int cfd,struct sockaddr_in sin)//服务器信息结构体传参 { //填充读写请求字符数组-->操作码+文件名+0+模式+0 char path[128]; printf("请输入要上传的文件路径:"); fgets(path,sizeof(path),stdin); path[strlen(path)-1]=0; char data[516]; short* code=(short*)data; *code=htons(2); char* pathname=data+2; strcpy(pathname,path); char* mode=pathname+strlen(pathname)+1; strcpy(mode,"octet"); int size=4+strlen(pathname)+strlen(mode); //向服务器发送下载请求 if(sendto(cfd,data,size,0,(struct sockaddr*)&sin,sizeof(sin))==-1) { perror("sendto error"); return; } socklen_t socklen=sizeof(sin);//接受服务器信息结构体容器 int fd=open(path,O_RDONLY); if(fd==-1) { perror("open error"); return; } int hblock=1;//数据包块编码号从1开始 while(1) { memset(data,0,516); //接收应答包 if(recvfrom(cfd,data,516,0,(struct sockaddr*)&sin,&socklen)==-1) { perror("recvfrom error"); return; } int res=read(fd,data+4,516-4); short *p1=(short*)data; *p1=htons(3); *(p1+1)=htons(hblock++); //发送数据包 if(sendto(cfd,data,res+4,0,(struct sockaddr*)&sin,sizeof(sin))==-1) { perror("sendto error"); return; } if(res==0) { printf("上传完毕\n"); break; } } close(fd); } //文件下载 void download(int cfd,struct sockaddr_in sin) { //填充读写请求字符数组-->操作码+文件名+0+模式+0 char filename[32]; printf("请输入要下载的文件名:"); fgets(filename,sizeof(filename),stdin); filename[strlen(filename)-1]=0; char data[516]=""; short *code=(short*)data; *code=htons(1); char* file=data+2; strcpy(file,filename); char* mode=file+strlen(file)+1; strcpy(mode,"octet"); int size=4+strlen(file)+strlen(mode); if(sendto(cfd,data,size,0,(struct sockaddr*)&sin,sizeof(sin))==-1) { perror("sendto error"); return; } socklen_t socklen=sizeof(sin); int fd=open(filename,O_CREAT|O_WRONLY,0664); while(1) { memset(data,0,516); //接收数据包 int len=recvfrom(cfd,data,516,0,(struct sockaddr*)&sin,&socklen); if(len==-1) { perror("recvfrom error"); return; } write(fd,data+4,len-4); if(len<516) { printf("下载完毕\n"); break; } short *p1=(short*)data; *p1=htons(4); //发送应答包 if(sendto(cfd,data,4,0,(struct sockaddr*)&sin,sizeof(sin))==-1) { perror("sendto perror"); return; } } close(fd); } int main(int argc, const char *argv[]) { //创建客服端套接字 int cfd=socket(AF_INET,SOCK_DGRAM,0); if(cfd==-1) { perror("socket error"); return -1; } printf("socket success cfd=%d\n",cfd); //填充客户端信息结构体绑定 struct sockaddr_in cin; cin.sin_family=AF_INET; cin.sin_port=htons(CLI_PORT); cin.sin_addr.s_addr=inet_addr(CLI_IP); if(bind(cfd,(struct sockaddr*)&cin,sizeof(cin))==-1) { perror("bind error"); return -1; } printf("bind success\n"); //填充服务器信息结构体 struct sockaddr_in sin; sin.sin_family=AF_INET; sin.sin_port=htons(SER_PORT); sin.sin_addr.s_addr=inet_addr(SER_IP); int ch; while(1) { printf("请选择要操作的选项:\n"); printf("1.上传\n"); printf("2.下载\n"); printf("3.退出\n"); scanf("%d",&ch); while(getchar()!=10); switch(ch) { case 1: upload(cfd,sin); break; case 2: download(cfd,sin); break; case 3: return 1; default: printf("输入错误请重新输入\n"); break; } } close(cfd); return 0; }2.tcp多进程多线程实现并发服务器
3. 流式域套接字、报式域套接字实现同一主机之间通信
