win32 tcp文件传输并发服务器
#include<stdio.h> #include <stdlib.h> #include <winsock2.h> #include <string.h> #pragma comment(lib,"ws2_32.lib") #define PORT 9999 #define IPADDR "127.0.0.1" #define BACKLOG 20 #define FILENAME 200 #define LENGTH 200 #define BUFFERSIZE 1024 struct FILEHEAD //FILE-head struct { char filename[LENGTH];//file name unsigned int length;//the byte of the file }; struct FILEDATA //FILE-data struct { char filename[LENGTH];//file name char package[BUFFERSIZE];//package data unsigned int length;//the byte of the file unsigned int index;//index of the package }; struct sockaddr_in clientaddr; //Definition of the external variable for thread function call void getFileInformation(FILEHEAD file) { printf( "file information :\n" ); printf( " Filename: %s\n", file.filename ); //printf( " Ext: %s\n", file.ext ); printf( " the file length is: %ld btye\n", file.length ); } void showClientinfo() { //获取当前系统时间 SYSTEMTIME st; GetLocalTime(&st); char SysDate[30]; //将systime中的时间转变为字符串存入SysDate[30]; sprintf(SysDate, "%4d-%2d-%2d %2d:%2d:%2d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); //Server显示客户端信息 printf("%s Recv from Client [%s:%d] : %s\n", SysDate, inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port)); //服务器向客户端回显信息 } DWORD WINAPI requestThread(LPVOID lparam) { FILEHEAD filehead; FILEDATA filedata; SOCKET newsock=(SOCKET)(LPVOID)lparam; //char buf[BUFFERSIZE]={0}; memset(&filehead,0,sizeof(filehead)); memset(&filedata,0,sizeof(filedata)); showClientinfo(); //printf("等待文件头信息 ...\n"); int length_file_info=recv(newsock,(char *)&filehead,sizeof(filehead),0); if (SOCKET_ERROR==length_file_info) { printf("receive failed!\n"); closesocket(newsock); return -1; } if (length_file_info<=0) { exit(1);//异常退出 } getFileInformation(filehead);//打印文件信息 FILE *fp=NULL; fp=fopen(filehead.filename,"wb+"); if (NULL==fp) { perror("fail to build the file!!!\n"); exit(1); } //printf("要接收的文件名为:"); //printf(filehead.filename);//打印文件名 //printf ("\n catch file now....\n"); int recv_length=0;//接收到字节的长度 //Sleep(100); printf("开始接收...\n"); filedata.index=0; while (1) { recv_length=recv(newsock,(char *)&filedata,sizeof(filedata),0); if (recv_length == SOCKET_ERROR) { printf("recv failed !\n"); closesocket(newsock); //WSACleanup(); return -1; } fwrite(filedata.package,1,BUFFERSIZE,fp); if (0==recv_length) { break; } //printf("第%d块接收成功!\n",filedata.index); } printf("\n接收完成...\n\n"); fflush(fp); fclose(fp); fp=NULL; return 0; } int main(int argc,char *argv[]) { //初始化winsock版本信息,加载动态链接库(dll) WSADATA wsData; if (WSAStartup(MAKEWORD(2,2),&wsData)!=0) { printf("WSAStartup failed !!!\n"); return -1; } //创建套接字 SOCKET socklisten; if((socklisten=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET) { printf("socket failed!!!\n"); WSACleanup(); return -1; } //设置服务器地址 struct sockaddr_in servaddr; memset(&servaddr,0,sizeof(servaddr)); servaddr.sin_family=AF_INET; servaddr.sin_port=htons(PORT); servaddr.sin_addr.S_un.S_addr=inet_addr(IPADDR); //绑定socket地址结构到监听套接字 if (bind(socklisten,(sockaddr *)&servaddr,sizeof(servaddr))!=0) { printf("binding failed!!!\n"); closesocket(socklisten); WSACleanup(); } //在server上运行监听 if (listen(socklisten,20)!=0) { printf("listen failed !!!\n"); closesocket(socklisten); WSACleanup(); return -1; } //接收客户端的连接请求 printf("TCP server is start!!!\n"); //clientaddrlength要有初值, int client_addr_length = sizeof(clientaddr); memset(&clientaddr,0,client_addr_length); SOCKET connect; //循环等待 while (1) { if ((connect=accept(socklisten,(sockaddr *)&clientaddr,&client_addr_length))==INVALID_SOCKET) { printf("accept failed!!!\n"); closesocket(connect); WSACleanup(); return -1; } //创建新线程 DWORD ThreadID; CreateThread(NULL,0,requestThread,(LPVOID)connect,0,&ThreadID); } }