




已阅读5页,还剩3页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
计算机网络 实验报告实验三:编写客户服务器程序班级 xxxxx 姓名 xxxxxxxxxxxxx 学号 xxxxxxxxx 日期 xxxxxxxx 一、 实验目的:学习TCP/UDP协议套接字编程,深入理解客户服务器程序的原理,以及端口作用等。二、 实验内容编写客户服务器程序,服务器运行后等待客户连接,一旦收到客户送来的信息,立即回送回去。 客户机等待用户输入信息,然后发送给服务器。并接受服务器回送回来的信息。所有的信息均需显示在屏幕上。三、 程序实现设计方法编写客户服务器程序,服务器运行后等待客户连接,一旦收到客户送来的信息,立即送回去。客户机等待用户输入信息,然后发送给服务器。并接受服务器回送回来的信息。所有的信息均需显示在屏幕上。可以每2个人一组,一个负责服务器端,一个负责客户端。(自己协商使用udp还是tcp方式,端口号)上机实验过程:1、启动winXP,运行vc程序2、新建一个文件,录入编辑好的服务器程序或客户程序3、分别以server.c或client.c保存4、打开buildcompile菜单,系统会自动建立一个新的工程,然后完成编译工作5、打开projectsettings.菜单,在对话框的link标签下,找到project options:编辑框,在其中添加“WS2_32.LIB ”6、打开buildbuild菜单,系统生成执行程序server.exe或client.exe7、分别运行server.exe,client.exe,观察两个程序运行结果四、 源程序服务器端程序/*Windows环境下使用VC编写的TCP通信服务器端程序*在编译这个程序时,需要在工程设置项目-连接项目中添加如下两项:* Ws2_32.lib和Winmm.lib*否则编译后链接生成可执行文件时会出错!*服务器程序在单机内的测试运行方法:* server 监听端口:缺省为9999* *程序中的函数列表:*int InitSockets(void): 插口(套接字)初始化*void ServeAClient(LPVOID lpv):为客户提供服务的函数*int ServerLoop(SOCKET sd_listen, int isMultiTasking):* 服务器循环函数,服务期间总是在这个函数中循环*/#include #include #include /*由于Winsock目前有两个版本:2.2和1.1,所以我们首先必须判断系统所支持的Winsock版本,这就要靠WSAStartup函数了。另外还有一个WSACleanup函数,这两个函数是Winsock编程必须调用的,其中WSAStartup函数的功能是初始化Winsock DLL,因为在Windows下,Socket是以DLL的形式实现的。1.1版本的DLL为Winsock.dll,而2.2版本的DLL则为Wsock32.dll,其中在2.2版本的系统中,对Winsock1.1函数的调用会由Wsock32.dll自动映射到Winsock.dll。WSAStartup函数的功能就是初始化DLL,其函数原型为: int WSAStartup (WORD wVersionRequested,LPWSADATA lpWSAData); 其第一个参数为你所想需要的Winsock版本!低字节为主版本,高字节为副版本!由于目前Winsock有两个版本:1.1和2.2,因此该参数可以是0x101或0x202;第2个参数是一个WSADATA结构,用于接收函数的返回信息!WSAStartup函数调用成功会返回0,否则返回非0值! 由于Win 95,WinNT4自带的Winsock是1.1版本的,所以如果你的程序是基于Winsock2.2的,那很可能无法在上面运行。因此,如果你希望你写的程序被所有Windows平台支持的话,最好将其声明成1.1版的,不过这样将无法使用很多Winsock2.2才有的特性!至于WSACleanup的用法很简单,用“WSACleanup();”就行了!另外,在DLL内部维持着一个计数器,只有第一次调用WSAStartup才真正装载DLL,以后的调用只是简单的增加计数器,而WSACleanup函数的功能则刚好相反,每调用一次使计数器减1,当计数器减到0时,DLL就从内存中被卸载!因此,你调用了多少次WSAStartup,就应相应的调用多少次的WSACleanup!*/int InitSockets(void) WSADATA wsaData; WORD wVersionRequested; int err; /* Ask for Winsock 1.1 functionality */ wVersionRequested = MAKEWORD( 1, 1 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) printf(Error %d: Winsock not availablen, err); return 1; return 0;#define WSA_ERROR(x) printf(Error %d: %sn, WSAGetLastError(), x); return 1; int ServerLoop(SOCKET sd_listen, int isMultiTasking);main(int argc, char *argv) SOCKET sd_listen; int err; u_short iPort; struct sockaddr_in addr_srv; struct hostent *ptrHost; iPort = (argc = 2) ? atoi(argv1) : 9999;/从命令行中提取服务器监控的端口号,如果命令行没有带数字格式的端口号,则定为9999 InitSockets();/初始化套接字/*创建套接字有两个函数,socket和WSASocket,前者是标准的Socket函数,而后者是微软对Socket的扩展函数。socket函数有3个参数,第一个是指定通信发生的区域,在UNIX下有AF_UNIX、AF_INET、AF_NS等,而在Winsock1.1下只支持AF_INET,到了2.2则添了AF_IRDA(红外线通信)、AF_ATM(异步网络通信)、AF_NS、AF_IPX等;第2个参数是套接字的类型,在AF_INET地址族下,有SOCK_STREAM、SOCK_DGRAM、SOCK_RAW三种套接字类型。SOCK_STREAM也就是通常所说的TCP,而SOCK_DGRAM则是通常所说的UDP,而SOCK_RAW则是用于提供一些较低级的控制的;第3个参数依赖于第2个参数,用于指定套接字所用的特定协议,设为0表示使用默认的协议。socket函数调用成功返回一个套接字描述符,错误则返回SOCKET_ERROR。 */ sd_listen = socket(PF_INET, SOCK_STREAM, 0); if (sd_listen = INVALID_SOCKET) printf(Error: out of socket resourcesn); return 1; /*接下来要为服务器端定义的这个监听的socket指定一个地址及端口(Port),这样客户端才知道要连接哪一个地址的哪个端口,为此我们首先设置数据结构struct sockaddr中的参数,随之调用bind()函数将socket邦定在指定的端口和地址上,该函数调用成功返回0,否则返回SOCKET_ERROR。sockaddr_in结构的sinaddrs_addr成员被设置为INADDR_ANY,意味着由操作系统给socket自动指定一个最有效的IP地址。*/ addr_srv.sin_family = PF_INET; addr_srv.sin_addr.s_addr = htonl(INADDR_ANY); addr_srv.sin_port = htons(iPort); err = bind(sd_listen, (const struct sockaddr *) &addr_srv, sizeof(addr_srv); if (err = INVALID_SOCKET) WSA_ERROR(Error: unable to bind socketn)/*当服务器端的Socket对象绑定完成之后,服务器端必须通知操作系统为这个socket建立一个监听队列来接收客户端的连接请求。listen()函数使服务器端的Socket 进入监听状态,并设定可以建立的最大连接数。该函数调用成功返回0,否则返回SOCKET_ERROR。*/ err = listen(sd_listen, SOMAXCONN); if (err = INVALID_SOCKET) WSA_ERROR(Error: listen failedn)/程序进入服务循环函数 ServerLoop(sd_listen, 1); printf(Server is downn); WSACleanup(); return 0;/*如果客户端发来HELLO SERVER,那么服务器端将回送HELLO CLIENT,不符合的输入,服务器端将没有响应*/void ServeAClient(LPVOID lpv) SOCKET sd_accept = (SOCKET) lpv; const char *msg = HELLO CLIENT; char response4096; memset(response, 0, sizeof(response); recv(sd_accept, response, sizeof(response), 0); if (strcmp(response, HELLO SERVER) printf(Application: client not using expected protocol %sn, response); else send (sd_accept, msg, strlen(msg)+1, 0); closesocket(sd_accept);#define MAX_SERVED 3/服务器端的循环函数,服务期间总是在这个函数中运行int ServerLoop(SOCKET sd_listen, int isMultiTasking) SOCKET sd_accept; struct sockaddr_in addr_client; int err, nSize; int numServed = 0; HANDLE handlesMAX_SERVED; int myID; /主循环体,服务期间总是在这个结构内循环 while (numServed MAX_SERVED) nSize = sizeof(addr_client); /在套接字sd_listen上接收到客户端的连接请求后,建立一个新的套接字sd_accept, /使用套接字sd_accept与客户端进行通信 sd_accept = accept(sd_listen, (struct sockaddr *) &addr_client, &nSize); if (sd_accept = INVALID_SOCKET) WSA_ERROR(Error: accept failedn) printf(Accepted connection from client at %sn, inet_ntoa(addr_client.sin_addr); /如果服务器端允许工作在并发多任务模式(isMultiTasking为程序员设定的标志) if (isMultiTasking) #ifdef _WIN32 /适应不同版本的编译环境,较新的系统都定义了_WIN32 / 建立一个新的线程,线程程序代码为ServeAClient,传递的参数为通信套接字sd_accept handlesnumServed = CreateThread(NULL, 1000, (LPTHREAD_START_ROUTINE)ServeAClient, (LPVOID) sd_accept, 0, &myID);#else myID = fork(); if (myID = 0) /* I am child process */ ServeAClient (LPVOID) sd_accept); exit(0); handlesnumServed = myID;#endif else ServeAClient(LPVOID) sd_accept); numServed+; if (isMultiTasking) #ifdef _WIN32 /等待线程组handles中的线程结束,并显示运行状态 err = WaitForMultipleObjects(MAX_SERVED, handles, TRUE, INFINITE); printf(Last thread to finish was thread #%dn, err);#endif return 0;客户端程序/*Windows环境下使用VC编写的TCP通信客户端程序*在编译这个程序时,需要在工程设置项目-连接项目中添加如下两项:* Ws2_32.lib和Winmm.lib*否则编译后链接生成可执行文件时会出错!*客户端程序在单机内的测试运行方法:* client 主机名 端口号* *程序中的函数列表:*int InitSockets(void): 插口(套接字)初始化*/#include #include int InitSockets(void) WSADATA wsaData; WORD wVersionRequested; int err; /* Ask for Winsock 1.1 functionality */ wVersionRequested = MAKEWORD( 1, 1 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) printf(Error %d: Winsock not availablen, err); return 1; return 0;#define WSA_ERROR(x) printf(Error %d: %sn, WSAGetLastError(), x); return 1; /void InitSockets(void);main(int argc, char *argv) SOCKET sd_client; int err; u_short iPort; struct sockaddr_in addr_srv; struct hostent *ptrHost; char response4096; char *pszHost; char *msg = HELLO SERVER; if (argc = 3) pszHost = argv1; iPort = atoi(argv2); else printf(Usage:t client1 hostname portno); return 1; InitSockets(); sd_client = socket(PF_INET, SOCK_STREAM, 0); if (sd_client = INVALID_SOCKET) WSA_ERROR(no more socket resources)/输入了数字格式的主机名,则直接转换,否则通过gethostbyname获取主机IP if (atoi(pszHost) u_long ip_addr = inet_a
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 公司文体活动月策划方案
- 公司着装大赛策划方案
- 公司新年嘉年华活动方案
- 2025年职业健康安全管理师考试试卷及答案
- 2025年新能源与可再生能源知识考核考试卷及答案
- 2025年数字信号处理技术考试卷及答案
- 2025年天文学与空间科学考试题及答案
- 2025年人机交互设计师职业资格考试试题及答案
- 2025年企业管理咨询师职业资格考试试卷及答案
- 2025年交通工程与智能交通管理的专业知识考试试卷及答案
- 国开《学前儿童语言教育活动指导》形考1-4试题及答案
- 海康2023综合安防工程师认证试题答案HCA
- 浊度仪使用说明书
- GB/T 14404-2011剪板机精度
- GB/T 14294-1993组合式空调机组
- GA 1517-2018金银珠宝营业场所安全防范要求
- 提高痰留取成功率PDCA课件
- 组合导航与融合导航解析课件
- 伊金霍洛旗事业编招聘考试《行测》历年真题汇总及答案解析精选V
- 深基坑支护工程验收表
- 颅脑CT影像课件
评论
0/150
提交评论