📄 server.c.bak
字号:
/*服务器主程序*/#include "mysocket.h"#include "des.h"/*模块变量定义*/static des_context ctx;static char des_key[8] = {0x20,0x05,0xAF,0x45,0xA3,0xF1,0x80,0x78}; //解密密码,必须和客户端完全一致./*模块函数定义*/static int decode_data(const int count,char *input,char *output);static int rcv_data(int sockfd);/*消息处理函数*/void sig_handle(int signo){ pid_t pid; int stat; while((pid = waitpid(-1,&stat,WNOHANG)) > 0) printf("child %d terminated\n",pid); return ; }/*入口函数*/int main(int argc,char **argv){ int lsnfd,confd; pid_t childpid; socklen_t clilen; struct sockaddr_in cliaddr,servaddr; des_set_key(&ctx,des_key);//设置des加密的密码 lsnfd = socket(AF_INET,SOCK_STREAM,0);//使用tcp协议 if(lsnfd < 0) { printf("ERROR:create socket failed.\n"); exit(1); } memset(&servaddr,0,sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(8888);//监听端口设为8888,必须和客户端相同 if(bind(lsnfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) < 0)//邦定8888端口 { printf("ERROR:bind port failed.\n"); exit(1); } if(listen(lsnfd,LISTENQ) < 0)//监听端口 { printf("ERROR:listen error.\n"); exit(1); } signal(SIGCHLD,sig_handle);//注册消息处理函数 printf("\tYou are Welcome!\n\tI am waiting for a connection......\n"); while(1) { clilen = sizeof(cliaddr); //程序在此阻塞(停止,只有此程序返回后才执行后面的代码),只到有客户端进行连接 confd = accept(lsnfd,(struct sockaddr *)&cliaddr,&clilen); if(confd < 0) { if(errno == EINTR) { continue; } else { printf("ERROR:accept failed!\n"); exit(1); } } //建立连接成功. childpid = fork();//如果有连接进来,则创建一个子进程来处理数据的接收 if(childpid == 0) //childpid为零则表示当前是在子进程里 { int e = 0; close(lsnfd);//关闭父进程里的监听socket,因为子进程会复制父进程的所有资源 printf("OK:I received a connection!\n"); e = rcv_data(confd);//接收数据函数 exit(e); } close(confd);//当前是在父进程. } close(lsnfd);//关闭连接 exit(0);}/*对受到的数据进行解密操作,每次只能解密8个字节的内容,如果数据不能被8整除,则最后的数据不加密??*/static int decode_data(const int count,char *input,char *output){ int n;//,m; char *iptr = input; char *optr = output; if(!count || input == NULL || output == NULL) return (-1); for(n = count / 8; n > 0;n--) { des_decrypt( &ctx, iptr, optr);//使用des解密函数解密 iptr += 8; optr += 8; }#if 0 //How to deal with last bytes less than 8? I have no idea about it for now. //Do nothing may be a good idea. m = n % 8; bzero(optr + m,8 - m); des_encrypt( &ctx, iptr, optr);#endif return (0);}/*接收数据的函数参数sockfd是已经建立的socket连接的描述符*/static intrcv_data(int sockfd){ size_t e = 0; FILE *fd = NULL; unsigned int count = 0; char buf4receive[MAXLINE + 1] = {0}; if(sockfd < 0)//如果描述小于零则直接退出 { printf("ERROR:bad socket!\n"); return (-1); } fd = fopen("video","w"); //创建接收文件,命名为 video if(fd == NULL) //若创建文件失败则退出 { printf("ERROR:create file failed!\n"); return (-1); } while(1) { count = readn(sockfd,buf4receive,MAXLINE);//从socket连接读取数据 if(count > 0) //如果count大于零则表示读到了数据 { decode_data(count,buf4receive,buf4receive);//对数据进行解密 e = fwrite(buf4receive,sizeof(char),count,fd);//将解密后的数据写到文件里 //e是实际写到文件中的字节数,如果实际写的和我们要求的不同,则表示写文件出错 if(e != count) { printf("ERROR:write data to file failed!\n"); return (-1); } } else if(count == 0)//如果count等于零表示数据接收完了 { printf("OK:file transmittion completted!\n"); fclose(fd); return (0); } else if(count == -1)//如果count等于负一则表示读数据出错了 { printf("ERROR:read data failed!\n"); fclose(fd); return (-2); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -