云南大学软件学院计算机网络原理报.docx
云南大学软件学院计算机网络原理报云南大学软件学院 实 验 报 告 课程: 计算机网络原理实验 任课教师: 刘春花,刘宇 姓名: _ 学号: _ 专业:数字媒体技术 成绩: 姓名: _ 学号: _ 专业:数字媒体技术 成绩: 实验三、套接字编程 1实验目的: 两人一组,编写一个客户端、服务器程序,掌握Socket编程原理。 2实验环境: 连入局域网络的主机一台。 3实验指导: Socket API是实现进程间通信的一种编程设施,也是一种为进程间提供底层抽象的机制。理解socket编程模型及其原理。 4实验分析,回答下列问题。 a.运行指导书中的程序,并修改服务器的功能,附上修改后的源代码,并加关键代码注释。 客户端: #include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <conio.h> #include <winsock2.h> #include <windows.h> #pragma comment(lib,"ws2_32.lib") #define PORT 3490 /* 客户机连接远程主机的端口*/ #define MAXDATASIZE 100 /* 每次可以接收的最大字节*/ int _tmain(int argc, _TCHAR* argv) WORD wVersionRequested; WSADATA wsaData; int err = 0 ,rval = 0 ; SOCKET fd; struct sockaddr_in servaddr; struct hostent* hp; char buf1024 = "" wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) return -1; if (fd = socket(AF_INET, SOCK_STREAM, 0) < 0) printf("Can not create socket!"); exit(2); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(PORT); hp = gethostbyname("113.55.34.150"); /根¨´据Y服¤t务?器¡Â的Ì?网ª?络?计?算?/机¨²名?称?得Ì?到Ì?其?IP地Ì?址¡¤等̨¨信?息¡é memcpy(char*)&servaddr.sin_addr, (char*)hp->h_addr,hp->h_length); memset(servaddr.sin_zero, 0, sizeof(servaddr.sin_zero); /和¨ª服¤t务?器¡Â创ä¡ä建¡§连¢?接¨® rval = connect(fd, (sockaddr*)&servaddr, sizeof(servaddr); if (rval < 0) /创ä¡ä建¡§连¢?接¨®失º¡ì败㨹 printf("Can not create connect!"); exit(3); else for(;) servaddr.sin_addr.S_un.S_addr=inet_addr("113.55.34.150"); memset(buf, 0, 1024); printf("Please input a line to server:"); scanf("%s",&buf); rval = send(fd, buf, strlen(buf) + 1,0); if(rval < 0) printf("Write error!"); if(rval=recv(fd,buf,sizeof(buf),0)<0) perror("reading stream message"); printf("server said :%sn",buf); if(rval=0) closesocket(fd); exit(5); 服务器: #include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include<conio.h> #include<winsock2.h> #include<windows.h> #pragma comment(lib,"ws2_32.lib") #define MYPORT 3490 /*定¡§义°?用®?户¡ì连¢?接¨®端?口¨²*/ #define BACKLOG 10 /*多¨¤少¦¨´等̨¨待äy连¢?接¨®控?制?*/ #define SERVER_IP_ADDR "192.168.1.102" /*服¤t务?器¡Â的Ì?IP地Ì?址¡¤*/ int _tmain(int argc, _TCHAR* argv) SOCKET sock, msgsock; int length = 0; struct sockaddr_in server; struct sockaddr tcpaddr; char buf1024 = "" int rval= 0, len= 0, err = 0; WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) return -1; sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) perror("opening stream socket"); exit(1); server.sin_family = AF_INET; server.sin_port = htons(MYPORT); server.sin_addr.s_addr = inet_addr(SERVER_IP_ADDR); memset(server.sin_zero, 0, sizeof(server.sin_zero); rval = bind(sock, (struct sockaddr *)&server, sizeof(server); if (rval < 0) perror("binding stream socket"); exit(1); length = sizeof(server); if (getsockname(sock, (struct sockaddr *)&server, &length) < 0) perror("getting socket name"); exit(1); printf("socket port #%dn", ntohs(server.sin_port); listen(sock, 5); len = sizeof(struct sockaddr); do msgsock = accept(sock, (struct sockaddr *)&tcpaddr, (int *)&len); if (msgsock = -1) perror("accept"); else for(;) memset(buf, 0, sizeof(buf); if ( (rval = recv(msgsock, buf, sizeof(buf),0) < 0) perror("reading stream message"); if (rval = 0) printf("client said :%sn",buf); printf("server->"); scanf("%s",&buf); rval=send(msgsock,buf,strlen(buf)+1,0); closesocket(msgsock); while (TRUE); closesocket(msgsock); return 0; b给出程序调试和运行的截图。 答:在客户端修改的程序: 尤其注意后面一句一定要加,否则程序运行失败 服务器程序代码的修改: 我作为客户端与服务器的交流截图: c.回答下列问题: 为什么在服务器和客户端要包含winsock2.h文件? 答:因为后面的ws2_32.lib是winsock2.h头文件包含的内容。且winsock2.h一定要放在windows.h上面,否则运行时会出现错误。 为什么在服务器和客户端程序中要加入#pragma comment(lib,"ws2_32.lib") 语句,如果不加会出现什么问题? 答:这个语句表示调用名为lib,"ws2_32.lib"的库,如果不加,编译时会出现错误,程序不能运行。 为什么在服务器和客户端程序中要使用WSAStartup函数,如果不用程序会有什么问题? 答: WSAStarup函数是Windows SocKNDs Asynchronous的启动命令、Windows下的网络编程接口软件 Winsock1 或 Winsock2 里面的一个命令,我们需要通过WSAStartup函数完成对Winsock服务的初始化,如果没有这个函数,服务无法初始化,从而影响程序的运行。 如果服务器程序中没有memset(server.sin_zero, 0, sizeof(server.sin_zero);语句,程序会出现什么错误,为什么? 答:将不会造成客户端不能与服务器进行正常的连接,因为该函数实现了将服务器地址与socket绑定在一起 如果先运行客户端程序,程序会有什么现象,为什么会有这一现象? 答:如果先运行客户端程序,则会显示无法连接到服务器。有这一现象的原因是服务器没运行,客户段无法寻找到对应IP的服务器。 如果服务器程序所在计算机没有连接网络,程序会发生什么错误?我们捕获到什么错误信息? 答:如果服务器程序所在计算机没有连接网络,则会显示不能建立连接。因此我们做这个试验的时候一定保持电脑是连网状态。 总结实验过程中出现的问题和解决的办法。 刚开始对于socket编程不是很了解,所以在运行程序及调试程序的过程中存在很多的问题,比如看不懂程序中某段代码的意义,不清楚程序的轮廓。鉴于此,通过老师在课堂上对程序的讲解及课下上网的搜索,慢慢的大致清楚了程序设计的基本思路。 本实验要求对原程序代码进行修改,以实现更多的功能,而我刚开始在理解程序方面存在着问题,所以在修改程序时摸不着头绪,不知从何下手,后来通过不断的实践及请教同学,在清楚了程序代码的思路及含义后渐渐的理清了头绪。