网上找的:聊天,文件传输 控制台小工具

来源:互联网 发布:夏侯瑾轩 知乎 编辑:程序博客网 时间:2024/04/20 11:07
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <Winsock2.h>#include <process.h>#include <time.h>#pragma comment(lib,"Ws2_32")#define M 512000 //每块传送文件的大小500k#define portNum 8888 //使用的端口号void LongToChar(long x,char a[]);//将long型整数转换成字符串long StrToLong(char str[]);//将字符串转换成long型整数void getW_name(char waddr[],char wname[]);   //获取文件名函数void sendFile(SOCKET ss); //服务端发送文件函数int receiveFile(SOCKET sc);//客户端接收文件函数void chatting_client(SOCKET sc); //客户端聊天函数void chatting_server(SOCKET s_d); //服务端聊天函数int client(); //客户端主程序void server(); //服务端主程序void main(){system("cls");system("@color 0a");puts("\n");puts("  *********************************************************");puts("      *  * ");puts("      *   欢·迎·使·用·局·域·网·文·件·发·送·工·具  *");puts("      *               * ");puts("      *  * ");puts("      *  * ");puts("      *        1.   客  户  端        * ");puts("      *  * ");puts("      *       2.   服  务  端               * ");puts("      *  * ");puts("      *       3.   结      束     * ");puts("      *  * ");puts("      *  * ");puts("      *      天乐软件工作室制作  * ");puts("      *  2008-3-1   * ");puts("      *      版权所有★欢迎传播    * ");puts("      *********************************************************\n");puts("全屏(退出全屏)操作请按:ALT+ENTER\n");printf("请输入你要选择的端代号(1-3):");char ch;char Num[10];gets(Num);ch=Num[0];while(ch >='4' || ch <='0')//检测用户选择的代码是否符合要求{printf("\n你的输入有误!请重新输入:");gets(Num);ch=Num[0];}if('1'==ch){client();}else if('2'==ch){server();}else if('3'==ch){exit(0);}}int client(){system("color 0a");//修改DOS窗口颜色,是其成0A。WORD wVersion=MAKEWORD(1,1); WSADATA wsData; int nResult= WSAStartup(wVersion,&wsData);  //启动WINSOCKETif(nResult !=0) { printf("启动Winsock失败!\n"); } SOCKET sc=socket(AF_INET,SOCK_STREAM,IPPROTO_IP);  //创建套接字if(sc==INVALID_SOCKET) { printf("创建套接字失败!\n"); } SOCKADDR_IN addrSc;addrSc.sin_family=AF_INET; addrSc.sin_port=htons(portNum); //保证字节顺序 char IP[20];again:printf("请输入服务器的IP地址:");gets(IP);if( -1==inet_addr(IP) )   //循环检测IP地址是否合法{printf("IP地址错误!\n");goto again;}addrSc.sin_addr.S_un.S_addr=inet_addr(IP); int b=0;while(b<5)               //检测5次,如果服务器在此时间内启动,则进行连接{nResult=connect(sc,(SOCKADDR*)&addrSc,sizeof(SOCKADDR)); //套接字连接Sleep((DWORD)100);//延时1秒if(nResult==SOCKET_ERROR) { printf("  %d 次连接失败!\n",b+1);}elsebreak;b++;}if(nResult==SOCKET_ERROR){printf("登陆超时,请重新登陆!\n");goto again;}char *buf="连接成功!";                   //向服务端验证连接成功nResult=send(sc,buf,strlen(buf)+1,0); if(nResult==SOCKET_ERROR){ printf("5.套接字发送数据失败!\n");return 0;}char mess[M];nResult =recv(sc,mess,strlen(mess),0);     //接受服务端的连接验证信息if(nResult == -1 )                         //判断服务端是否关闭{printf("\n服务端已断开\n");system("pause");exit(0);}printf("%s\n",mess);///////////////////////////////////////////////////////////////////////////////                       功能菜单及操作                              ///////////////////////////////////////////////////////////////////////////////tianle:system("cls");             //清屏puts("\n\n");puts("  *********************************************************");puts("      *  * ");puts("      *   欢·迎·使·用·局·域·网·文·件·发·送·工·具  *");puts("      *(客   户   端)  * ");puts("      *  * ");puts("      *  * ");puts("      *   请等待服务端的相应操作  * ");puts("      *  * ");puts("      *  * ");puts("      *      天乐软件工作室制作  * ");puts("      *  2008-3-1   * ");puts("      *      版权所有★欢迎传播    * ");puts("      *********************************************************\n");puts("全屏(退出全屏)操作请按:ALT+ENTER\n");char rMess[100];nResult=recv(sc,rMess,strlen(rMess),0);         //接收服务端发来的操作请求if(nResult==-1)                              //判断服务端是否关闭{printf("\n服务端已断开\n");system("pause");goto tianle;}printf("%s\n",rMess);char ch;char str[100];gets(str);ch=str[0];while( ch!='Y' && ch!='y' && ch!='N' && ch!='n' ) //处理客户端的错误输入{printf("输入有误,请重新输入(Y/N):");gets(str);ch=str[0];}send(sc,&ch,sizeof(char),0); //向服务端反馈选择,并执行相应操作if(strcmp(rMess,"服务端向你传送文件,是否接受(Y/N):")==0 && (ch=='Y' || ch=='y') ){receiveFile(sc);}if(strcmp(rMess,"服务端向你发起聊天,是否接受(Y/N):")==0 && (ch=='Y' || ch=='y') ){chatting_client(sc);}if(ch=='N' || ch=='n'){printf("你拒绝了!\n");system("pause");}system("cls");goto tianle;nResult=closesocket(sc);  //关闭套接字if(nResult==SOCKET_ERROR) { printf("8.关闭套接字失败!\n");return 0;} }void server(){system("color 0a");//修改DOS窗口颜色为0AWORD wVersion=MAKEWORD(1,1); WSADATA wsData; int nResult= WSAStartup(wVersion,&wsData); //1、启动Winsockif(nResult !=0) { printf("启动Winsock失败!\n"); } SOCKET s=socket(AF_INET,SOCK_STREAM,IPPROTO_IP); //2.创建套接字if(s==INVALID_SOCKET) { printf("创建套接字失败!\n"); } SOCKADDR_IN addr; addr.sin_family=AF_INET; addr.sin_port=htons(portNum); //保证字节顺序 addr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);nResult=bind(s,(sockaddr*)&addr,sizeof(sockaddr)); //3、套接字的绑定if(nResult==SOCKET_ERROR) { printf("套接字的绑定失败!\n");} nResult=listen(s,5); //最多5个连接, 套接字的监听if(nResult==SOCKET_ERROR) { printf("套接字的监听(服务器端)失败!\n"); } SOCKADDR_IN addrClient;int len=sizeof(SOCKADDR);printf("\n等待客户端的连接");int a=0;while(a<5)//开始的一个小动态图形{for(int b=0;b<8;b++){Sleep(100);printf(" . ");}Sleep(100);system("cls");printf("\n\r等待客户端的连接");a++;}while(1){SOCKET s_d=accept(s,(sockaddr*)&addrClient,&len); //5、套接字等待连接::(服务器端) if(s_d==INVALID_SOCKET) { printf("套接字等待连接(服务器端)失败!\n");}char *success="成功登陆服务器!";send(s_d,success,strlen(success)+1,0);            //向客户端发送验证信息char mess[M]; nResult=recv(s_d,mess,strlen(mess),0); if(nResult == -1 )                               //判断服务端是否关闭{printf("\n客户端已断开\n");system("pause");exit(0);}printf("\n%s",mess);///////////////////////////////////////////////////////////////////////////////                       功能菜单及操作                              ///////////////////////////////////////////////////////////////////////////////again:system("@color 0a");system("cls");puts("\n");puts("  *********************************************************");puts("      *  * ");puts("      *   欢·迎·使·用·局·域·网·文·件·发·送·工·具  *");puts("      *(服   务   端)  * ");puts("      *  * ");puts("      *  * ");puts("      *   1.向 客 户 端 传 送 文 件   * ");puts("      *  * ");puts("      *  2.向 客 户 端 发 起 聊 天  * ");puts("      *  * ");puts("      *  3.结   束   服   务    端  * ");puts("      *  * ");puts("      *  * ");puts("      *      天乐软件工作室制作  * ");puts("      *  2008-3-1   * ");puts("      *      版权所有★欢迎传播    * ");puts("      *********************************************************\n");puts("全屏(退出全屏)操作请按:ALT+ENTER\n");printf("请输入你要选择的模块的代号(1-3):");char ch;char Num[10];gets(Num);ch=Num[0];while(ch >='4' || ch <='0')//检测用户选择的代码是否符合要求{printf("\n你的输入有误!请重新输入:");gets(Num);ch=Num[0];} if('1'==ch)    //发送文件模块的处理{char ch;char *str="服务端向你传送文件,是否接受(Y/N):";send(s_d,str,strlen(str)+1,0);printf("等待客户端回应……\n");nResult=recv(s_d,&ch,sizeof(char),0);if(nResult == -1 )                         //判断客户端是否关闭{printf("\n客户端已断开\n");system("pause");goto again;}if( ch=='Y' || ch=='y'){sendFile(s_d);goto again;}if(ch=='N'|| ch=='n'){printf("对方拒绝接受!\n");system("pause");goto again;}}if('2'==ch)//处理聊天模块{char ch;int flag=0;char *str="服务端向你发起聊天,是否接受(Y/N):";send(s_d,str,strlen(str)+1,0);printf("等待客户端回应……\n");nResult=recv(s_d,&ch,sizeof(char),0);       //判断客户端同意或不同意if(nResult == -1 )                         //判断客户端是否关闭{printf("\n客户端已断开\n");system("pause");goto again;}if( ch=='Y' || ch=='y' ){chatting_server(s_d);goto again;}if(ch=='N'|| ch=='n'){printf("对方拒绝接受!\n");system("pause");goto again;}}if('3'==ch){exit(0);          //结束程序}}nResult=closesocket(s); //关闭套接字。if(nResult==SOCKET_ERROR) { printf("8.关闭套接字(服务器端)失败!\n");} }void chatting_client(SOCKET sc){system("cls");system("color 0a");int receiveLength; char SMess[1000];//发送消息的缓存char RMess[1000];//接收消息的缓存char SName[200];//服务端用户的姓名char CName[200];//客户端用户的姓名int nResult;nResult=recv(sc,RMess,strlen(RMess),0);     //确认文件传送模块连接成功if( nResult== -1 )           //判断服务端是否关闭{printf("\n服务端已断开\n");system("pause");return ;}printf("%s\n",RMess);printf("请输入你的名字:");      //客户端用户的姓名gets(CName);while(strlen(CName)==0){printf("用户名不能为空! 请输入你的名字:\n");gets(CName);}send(sc,CName,strlen(CName)+1,0);   //向服务端发送姓名receiveLength=recv(sc,SName,200,0); //接收服务端用户的姓名if(receiveLength==-1)                //判断服务端是否关闭{printf("\n服务端已断开\n");system("pause");return ;}printf("你已和%s取的连接……\n",SName);printf("开始聊天(输入exit退出聊天程序)……\n");while(1){struct tm *local; time_t t;//调用时间函数,显示用户的操作时间t=time(NULL); local=localtime(&t); nResult=recv(sc,RMess,M,0); //接收服务端发送过来的消息if(nResult == -1)                //判断服务端是否关闭{printf("\n服务端已断开\n");system("pause");return ;}if(strcmp(RMess,"exit")==0){printf("服务端已退出聊天程序,本程序也即将退出!\n");system("pause");break;}printf("%s\t%d:%d:%d  \n    %s\n",SName,local->tm_hour,local->tm_min,local->tm_sec,RMess);printf("\n请输入信息:");      //客户端用户输入消息gets(SMess);if(strcmp(SMess,"exit")==0){send(sc,SMess,strlen(SMess)+1,0);printf("你已退出聊天程序!\n");system("pause");break;}//服务端显示自己的消息t=time(NULL); local=localtime(&t); printf("\r%s\t%d:%d:%d  \n    %s\n",CName,local->tm_hour,local->tm_min,local->tm_sec,SMess);send(sc,SMess,strlen(SMess)+1,0);}}void sendFile(SOCKET ss){char *str1="....确认成功....";send(ss,str1,strlen(str1)+1,0);//向客户端发送验证信息FILE *fp;long i;//文件分的的块数char fileAddr[300];char fileName[100];dmm:printf("请输入要传送的文件绝对地址(含文件名):");gets(fileAddr);if( (fp=fopen(fileAddr,"rb")) == NULL)   //打开文件{printf("文件地址输入错误!\n");goto dmm;}getW_name(fileAddr,fileName);send(ss,fileName,strlen(fileName)+1,0);  //发送文件名fseek(fp,0L,2);long fileLength=ftell(fp);//取得文件的长度fseek(fp,0L,0);char Length[100];LongToChar(fileLength,Length);send(ss,Length,strlen(Length)+1,0);//发送文件大小到客户端if( 0 == fileLength%M )//对文件进行分块{i=fileLength/M;}else{i=fileLength/M+1;}char mess[M];long readLength;//从文件读取的长度long sendLength;//发送文件的长度int k=1;//正在传送的模块号char *temp="开始接收文件";//向客户端开始传送,确认同步开始int nResult;nResult=recv(ss,mess,M,0);if(nResult == -1 )                   //判断客户端是否关闭{printf("\n客户端已断开\n");system("pause");return ;}send(ss,temp,strlen(temp)+1,0);printf("%s,共 %ld 模块:\n",mess,i);long total=0;while( k <= i ){Sleep((DWORD)800);//此非常重要,降低了传输时间,保证了两边的同步readLength=fread(mess,sizeof(char),M,fp);sendLength=send(ss,mess,readLength,0);total+=sendLength;printf("\r第 %d 模块   读取:%ldB  发送:%ldB",k,readLength,sendLength);printf("  进度: %2.2f%c  模块:%ld / %ld",100*(total*1.0/fileLength),37,k,i);if(sendLength==SOCKET_ERROR)   { printf("失败!");}k++;}fclose(fp);printf("\n文件发送完成!\n");system("pause");}void chatting_server(SOCKET s_d){system("color 0a");char *str1="你同意了……";send(s_d,str1,strlen(str1)+1,0);int receiveLength;//接收消息的长度char SMess[1000];//发送消息的缓存char RMess[1000];//接收消息的缓存char SName[200];//服务端用户的姓名char CName[200];//客户端用户的姓名receiveLength=recv(s_d,CName,200,0);if(receiveLength==-1) //判断客户端是否关闭{printf("客户端已断开\n");system("pause");return ;} printf("你已和%s取的连接……\n",CName);printf("请输入你的名字:");gets(SName);while(strlen(SName)==0)//循环检测用户名是否合法{printf("用户名不能为空!  请输入你的名字:\n");getchar();gets(SName);}send(s_d,SName,strlen(SName)+1,0);//向客户端发送姓名printf("\n开始聊天(输入exit退出聊天程序)……\n");while(1){struct tm *local; time_t t; t=time(NULL); local=localtime(&t); printf("\n\n请输入信息:");gets(SMess);if(strcmp(SMess,"exit")==0)   //用户输入‘exit’退出程序{send(s_d,SMess,strlen(SMess)+1,0);printf("你已退出聊天程序!\n");system("pause");break;}//在服务端显示自己的消息printf("\r%s\t%d:%d:%d\n    %s\n",SName,local->tm_hour,local->tm_min,local->tm_sec,SMess);send(s_d,SMess,strlen(SMess)+1,0);//在服务端显示客户端消息t=time(NULL); local=localtime(&t); receiveLength=recv(s_d,RMess,M,0);if(receiveLength==-1) //判断客户端是否关闭{printf("客户端已断开\n");system("pause");return ;}if(strcmp(RMess,"exit")==0){printf("\n客户端已退出聊天程序,本程序也即将退出!\n");system("pause");break;}printf("\n%s\t%d:%d:%d\n    %s\n",CName,local->tm_hour,local->tm_min,local->tm_sec,RMess);}}void getW_name(char waddr[],char wname[]){int i,k=0,j,w_len=strlen(waddr);for(i=w_len-1;i>=0;i--){if(waddr[i]=='\\')break;wname[k++]=waddr[i];}wname[k++]='\0';i=strlen(wname);for(j=0,k=i-1;j<i/2;j++,k--){char temp=wname[j];wname[j]=wname[k];wname[k]=temp;}}int receiveFile(SOCKET sc){system("color 0a");int nResult;char mess[M];nResult=recv(sc,mess,strlen(mess),0);    //确认文件传送模块连接成功if(nResult == -1 )                       //判断服务端是否关闭{printf("\n服务端已断开\n");system("pause");return 0;}printf("%s\n",mess);char fileName[50];nResult=recv(sc,fileName,50,0);       //接收文件名if(nResult == -1 )                    //判断服务端是否关闭{printf("\n服务端已断开\n");system("pause");return 0;}nResult=recv(sc,mess,M,0);             //接受文件的大小if(nResult == -1 )                    //判断服务端是否关闭{printf("\n服务端已断开\n");system("pause");return 0;}long fileLength=StrToLong(mess);      //取的待传送文件的长度long i;                              //存放文件块数if( 0 == fileLength%M )  //对文件按N单位进行分块{i=fileLength/M;}else{i=fileLength/M+1;}FILE *fp;//打开文件int k=1;    //当前正在接收文件的块数long receiveLength;//接收文件的长度long writeLength;//已写到文件的字符长度fp=fopen(fileName,"wb");char *temp="开始传送文件";send(sc,temp,strlen(temp)+1,0);//向客户端开始传送,确认同步开始nResult=recv(sc,mess,M,0);//接收服务端的确认消息if(nResult == -1 )                  //判断服务端是否关闭{printf("\n服务端已断开\n");system("pause");return 0;}printf("%s,共 %ld 模块:\n",mess,i);long total=0;//已接收文件的长度while(k<=i)                         //循环的接收文件{receiveLength=recv(sc,mess,M,0);if( receiveLength== -1 )        //判断服务端是否关闭{printf("\n服务端已断开\n");system("pause");return 0;}writeLength=fwrite(mess,sizeof(char),receiveLength,fp);printf("\r第 %d 模块   接收:%ldB  写入:%ldB",k,receiveLength,writeLength);total+=writeLength;printf("  进度: %2.2f%c  模块:%ld / %ld",100*(total*1.0/fileLength),37,k,i);k++;}fclose(fp);printf("\n文件接收完成!\n");system("pause");return 0;}void LongToChar(long x,char a[]){int count=0;if(x==0)return;while(x){a[count++]=x%10+'0';x=x/10;}a[count]='\0';for(int i=0,j=count-1;i<count/2;i++,j--){ char temp;  temp=a[i];  a[i]=a[j];  a[j]=temp;}}long StrToLong(char str[]){long result;bool bEnd;bEnd = true;result = 0;for ( int i = 0; bEnd; i++ ){if (str[i] != '\0' && str[i] >= '0' && str[i] <= '9'){result = result * 10 + str[i] - '0';}if (str[i] == '\0'){bEnd = false;}}return result;}


原创粉丝点击