并发套接字编程课程设计报告.docx
- 文档编号:5221465
- 上传时间:2022-12-14
- 格式:DOCX
- 页数:12
- 大小:419.87KB
并发套接字编程课程设计报告.docx
《并发套接字编程课程设计报告.docx》由会员分享,可在线阅读,更多相关《并发套接字编程课程设计报告.docx(12页珍藏版)》请在冰豆网上搜索。
并发套接字编程课程设计报告
《并发套接字编程》
课程设计报告
姓名:
王延兴
班级:
9班
学号:
54110904
《并发套接字编程》课程设计报告
班级:
11级9班学号:
54110904姓名:
王延兴
一、设计任务分析
(一)实验环境
操作系统:
Windows或Linux
编程工具及集成开发环境:
VC++
(二)实验目的和要求
实验目的:
掌握Linux或Windows平台上多线程、多进程或异步I/O的套接字编程。
实验要求:
(1)在Windows上,编写、编译1个客户机端程序和1个服务器端程序。
要求客户机端程序能发送请求给服务器端程序,服务器端程序收到后能发送本机时间给客户机端程序。
(2)在相同或不同机子上,先运行服务器端程序可执行文件,后运行客户机端程序可执行文件。
可选内容:
(1)编写Linux或Windows平台上采取各并发方式的1种程序。
(2)测试多线程、多进程或异步I/O的性能。
2、设计方案
本实验采用的多线程的编程方式实现了并发
◆各个函数功能:
DWORDWINAPIClientThread(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并发服务器
3、详细设计
服务器:
详细代码:
//multhreadServer.cpp:
Definestheentrypointfortheconsoleapplication.
//
#include"stdafx.h"
#include
#include
#pragmacomment(lib,"ws2_32.lib")
usingnamespacestd;
#include
#include
#definePORT4000
#defineIP_ADDRESS"127.0.0.1"
DWORDWINAPIClientThread(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)
{
cout<<"SendInfoError"< } while(true) { memset(RecvBuffer,0x00,sizeof(RecvBuffer));//为新申请的内存做初始化工作,其返回值为指向RecvBuffer的指针。 Ret=recv(CientSocket,RecvBuffer,MAX_PATH,0); if(Ret==0||Ret==SOCKET_ERROR) { cout<<"客户端退出! "< closesocket(CientSocket);//关闭客户端套接字 break; } cout<<"接收到客户信息为: "< } return0; } intmain(intargc,char*argv[]) { WSADATAWs; SOCKETServerSocket,CientSocket; structsockaddr_inLocalAddr,ClientAddr; intRet=0; intAddrLen=0; HANDLEhThread=NULL; //InitWindowsSocket if(WSAStartup(MAKEWORD(2,2),&Ws)! =0) { cout<<"InitWindowsSocketFailed: : "< return-1; } //CreateSocket ServerSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if(ServerSocket==INVALID_SOCKET) { cout<<"CreateSocketFailed: : "< return-1; } LocalAddr.sin_family=AF_INET; LocalAddr.sin_addr.s_addr=inet_addr(IP_ADDRESS); LocalAddr.sin_port=htons(PORT); memset(LocalAddr.sin_zero,0x00,8); //BindSocket Ret=bind(ServerSocket,(structsockaddr*)&LocalAddr,sizeof(LocalAddr)); if(Ret! =0) { cout<<"BindSocketFailed: : "< return-1; } Ret=listen(ServerSocket,10); if(Ret! =0) { cout<<"listenSocketFailed: : "< return-1; } cout<<"服务端已经启动"< while(true) { AddrLen=sizeof(ClientAddr); CientSocket=accept(ServerSocket,(structsockaddr*)&ClientAddr,&AddrLen); if(CientSocket==INVALID_SOCKET) { cout<<"AcceptFailed: : "< break; } cout<<"客户端连接: : "< "< hThread=CreateThread(NULL,0,ClientThread,(LPVOID)CientSocket,0,NULL); /*lpsa: 线程句柄的安全属性,比如子进程是否可以继承这个线程句柄,一般情况设置为NULL cbStack: 线程栈大小,一般取0表示默认大小 lpStartAddr: 线程入口函数 lpvThreadParam: 就是线程入口函数的参数,就是ThreadProc(void*lpParamete)的参数 fdwCreate: 控制线程创建的标志一般为0,表示线程立即启动。 如果你想创建之后把线程挂起来可以传入CREATE_SUSPENDED,传入这个参数你需要再适当的地方调用ResumeThread启动线程 lpIDThread: 是线程ID返回值,这个用来接收线程返回的ID*/ if(hThread==NULL) { cout<<"CreateThreadFailed! "< break; } CloseHandle(hThread); } closesocket(ServerSocket); closesocket(CientSocket); WSACleanup(); return0; } 客户端: 详细代码: //multhreadClient.cpp: Definestheentrypointfortheconsoleapplication. // #include"stdafx.h" #pragmacomment(lib,"ws2_32.lib") #include #include #include usingnamespacestd; #definePORT4000 #defineIP_ADDRESS"127.0.0.1" intmain(intargc,char*argv[]) { WSADATAWs;//存储被WSAStartup函数调用后返回值 SOCKETCientSocket; structsockaddr_inServerAddr; intRet=0; intAddrLen=0; HANDLEhThread=NULL; charSendBuffer[MAX_PATH]; //InitWindowsSocket if(WSAStartup(MAKEWORD(2,2),&Ws)! =0) { cout<<"InitWindowsSocketFailed: : "< return-1; } //CreateSocket CientSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if(CientSocket==INVALID_SOCKET) { cout<<"CreateSocketFailed: : "< 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) { cout<<"ConnectError: : "< return-1; } else { cout<<"连接成功! "< } charrecvbuf[100]; memset(recvbuf,0x00,sizeof(recvbuf)); Ret=recv(CientSocket,recvbuf,100,0); if(Ret==0||Ret==SOCKET_ERROR) { cout<<"接受失败! "< } cout<<"接收到的服务器端时间: "< while(true) { cin.getline(SendBuffer,sizeof(SendBuffer));//接受一个字符串,可以接收空格并输出 Ret=send(CientSocket,SendBuffer,(int)strlen(SendBuffer),0); if(Ret==SOCKET_ERROR) { cout<<"SendInfoError: : "< break; } } closesocket(CientSocket); WSACleanup(); return0; } ◆运行界面: 4、总结与体会 掌握Windows平台上多线程的套接字编程,同时实现了客户端可以一直向服务器发送信息的功能。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 并发 套接 编程 课程设计 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)