您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 管理学资料 > 《并发套接字编程》课程设计报告
《并发套接字编程》课程设计报告姓名:王延兴班级:9班学号:541109041《并发套接字编程》课程设计报告班级:11级9班学号:54110904姓名:王延兴一、设计任务分析(一)实验环境操作系统:Windows或Linux编程工具及集成开发环境:VC++(二)实验目的和要求实验目的:掌握Linux或Windows平台上多线程、多进程或异步I/O的套接字编程。实验要求:(1)在Windows上,编写、编译1个客户机端程序和1个服务器端程序。要求客户机端程序能发送请求给服务器端程序,服务器端程序收到后能发送本机时间给客户机端程序。(2)在相同或不同机子上,先运行服务器端程序可执行文件,后运行客户机端程序可执行文件。可选内容:(1)编写Linux或Windows平台上采取各并发方式的1种程序。(2)测试多线程、多进程或异步I/O的性能。二、设计方案本实验采用的多线程的编程方式实现了并发各个函数功能:2DWORDWINAPIClientThread(LPVOIDlpParameter)接收每个客户端连接的处理函数hThread=CreateThread(NULL,0,ClientThread,(LPVOID)CientSocket,0,NULL);创建进程send(CientSocket,tmp,(int)strlen(tmp),0);发送数据recv(CientSocket,RecvBuffer,MAX_PATH,0);接收数据WSAStartup(MAKEWORD(2,2),&Ws)初始化套接字类库socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);创建套接字bind(ServerSocket,(structsockaddr*)&LocalAddr,sizeof(LocalAddr));绑定套接字listen(ServerSocket,10);侦听,队列大小为10设计思想:创建TCP并发服务器三、详细设计服务器:详细代码://multhreadServer.cpp:Definestheentrypointfortheconsoleapplication.//#includestdafx.h#includeiostream#includeWindows.h#pragmacomment(lib,ws2_32.lib)usingnamespacestd;#includewinsock2.h#includetime.h#definePORT4000#defineIP_ADDRESS127.0.0.1DWORDWINAPIClientThread(LPVOIDlpParameter)//接收每个客户端连接的处理函数{SOCKETCientSocket=(SOCKET)lpParameter;intRet=0;charRecvBuffer[MAX_PATH];//在VC++6.0中,MAX_PATH的值为260。time_tt=time(0);chartmp[64];strftime(tmp,sizeof(tmp),%Y/%m/%d%X%A本年第%j天%z,localtime(&t));Ret=send(CientSocket,tmp,(int)strlen(tmp),0);if(Ret==SOCKET_ERROR){3coutSendInfoErrorendl;}while(true){memset(RecvBuffer,0x00,sizeof(RecvBuffer));//为新申请的内存做初始化工作,其返回值为指向RecvBuffer的指针。Ret=recv(CientSocket,RecvBuffer,MAX_PATH,0);if(Ret==0||Ret==SOCKET_ERROR){cout客户端退出!endl;closesocket(CientSocket);//关闭客户端套接字break;}cout接收到客户信息为:RecvBufferendl;}return0;}intmain(intargc,char*argv[]){WSADATAWs;SOCKETServerSocket,CientSocket;structsockaddr_inLocalAddr,ClientAddr;intRet=0;intAddrLen=0;HANDLEhThread=NULL;//InitWindowsSocketif(WSAStartup(MAKEWORD(2,2),&Ws)!=0){coutInitWindowsSocketFailed::GetLastError()endl;return-1;}//CreateSocketServerSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if(ServerSocket==INVALID_SOCKET){coutCreateSocketFailed::GetLastError()endl;return-1;}4LocalAddr.sin_family=AF_INET;LocalAddr.sin_addr.s_addr=inet_addr(IP_ADDRESS);LocalAddr.sin_port=htons(PORT);memset(LocalAddr.sin_zero,0x00,8);//BindSocketRet=bind(ServerSocket,(structsockaddr*)&LocalAddr,sizeof(LocalAddr));if(Ret!=0){coutBindSocketFailed::GetLastError()endl;return-1;}Ret=listen(ServerSocket,10);if(Ret!=0){coutlistenSocketFailed::GetLastError()endl;return-1;}cout服务端已经启动endl;while(true){AddrLen=sizeof(ClientAddr);CientSocket=accept(ServerSocket,(structsockaddr*)&ClientAddr,&AddrLen);if(CientSocket==INVALID_SOCKET){coutAcceptFailed::GetLastError()endl;break;}cout客户端连接::inet_ntoa(ClientAddr.sin_addr):ClientAddr.sin_portendl;hThread=CreateThread(NULL,0,ClientThread,(LPVOID)CientSocket,0,NULL);/*lpsa:线程句柄的安全属性,比如子进程是否可以继承这个线程句柄,一般情况设置为NULLcbStack:线程栈大小,一般取0表示默认大小lpStartAddr:线程入口函数lpvThreadParam:就是线程入口函数的参数,就是ThreadProc(void*lpParamete)的参数fdwCreate:控制线程创建的标志一般为0,表示线程立即启动。如果你想创建之后5把线程挂起来可以传入CREATE_SUSPENDED,传入这个参数你需要再适当的地方调用ResumeThread启动线程lpIDThread:是线程ID返回值,这个用来接收线程返回的ID*/if(hThread==NULL){coutCreateThreadFailed!endl;break;}CloseHandle(hThread);}closesocket(ServerSocket);closesocket(CientSocket);WSACleanup();return0;}客户端:详细代码://multhreadClient.cpp:Definestheentrypointfortheconsoleapplication.//#includestdafx.h#pragmacomment(lib,ws2_32.lib)#includeiostream#includeWindows.h#includewinsock2.husingnamespacestd;#definePORT4000#defineIP_ADDRESS127.0.0.1intmain(intargc,char*argv[]){WSADATAWs;//存储被WSAStartup函数调用后返回值SOCKETCientSocket;structsockaddr_inServerAddr;intRet=0;intAddrLen=0;HANDLEhThread=NULL;charSendBuffer[MAX_PATH];6//InitWindowsSocketif(WSAStartup(MAKEWORD(2,2),&Ws)!=0){coutInitWindowsSocketFailed::GetLastError()endl;return-1;}//CreateSocketCientSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if(CientSocket==INVALID_SOCKET){coutCreateSocketFailed::GetLastError()endl;return-1;}ServerAddr.sin_family=AF_INET;ServerAddr.sin_addr.s_addr=inet_addr(IP_ADDRESS);ServerAddr.sin_port=htons(PORT);memset(ServerAddr.sin_zero,0x00,8);Ret=connect(CientSocket,(structsockaddr*)&ServerAddr,sizeof(ServerAddr));if(Ret==SOCKET_ERROR){coutConnectError::GetLastError()endl;return-1;}else{cout连接成功!endl;}charrecvbuf[100];memset(recvbuf,0x00,sizeof(recvbuf));Ret=recv(CientSocket,recvbuf,100,0);if(Ret==0||Ret==SOCKET_ERROR){cout接受失败!endl;}cout接收到的服务器端时间:recvbufendl;while(true){cin.getline(SendBuffer,sizeof(SendBuffer));//接受一个字符串,可以接收空格并输7出Ret=send(CientSocket,SendBuffer,(int)strlen(SendBuffer),0);if(Ret==SOCKET_ERROR){coutSendInfoError::GetLastError()endl;break;}}closesocket(CientSocket);WSACleanup();return0;}运行界面:89四、总结与体会掌握Windows平台上多线程的套接字编程,同时实现了客户端可以一直向服务器发送信息的功能。
本文标题:《并发套接字编程》课程设计报告
链接地址:https://www.777doc.com/doc-4958787 .html