计算机网络socket编程实验报告.docx
- 文档编号:567355
- 上传时间:2023-04-29
- 格式:DOCX
- 页数:6
- 大小:77.98KB
计算机网络socket编程实验报告.docx
《计算机网络socket编程实验报告.docx》由会员分享,可在线阅读,更多相关《计算机网络socket编程实验报告.docx(6页珍藏版)》请在冰点文库上搜索。
Socket编程实验报告
一、程序代码
(1)服务器端#include
#pragmacomment(lib,"ws2_32.lib")voidmain()
{WORDwVersionRequested;
WSADATAwsaData;interr;
wVersionRequested=MAKEWORD(1,1);
err=WSAStartup(wVersionRequested,&wsaData);if(err!
=0){return;}
if(LOBYTE(wsaData.wVersion)!
=1||HIBYTE(wsaData.wVersion)!
=1)
{WSACleanup();return;}
SOCKETsockSrv=socket(AF_INET,SOCK_STREAM,0);SOCKADDR_INaddrSrv;addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);addrSrv.sin_family=AF_INET;addrSrv.sin_port=htons(6000);
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));// 绑定端口listen(sockSrv,SOMAXCONN);//SOMAXCONN 由系统确定请求数SOCKADDR_INaddrClient;//连接上的客户端ip地址intlen=sizeof(SOCKADDR);
while
(1)
{SOCKETsockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
//接受客户端连接,获取客户端的ip地址charsendBuf[50];sprintf(sendBuf,"Welcome%sto
here!
",inet_ntoa(addrClient.sin_addr));// 组合消息发送出去send(sockConn,sendBuf,strlen(sendBuf)+1,0);// 发送消息到客户端charrecvBuf[50];recv(sockConn,recvBuf,50,0);// 接受客户端消息printf("%s\n",recvBuf);
closesocket(sockConn);WSACleanup();//断开连接
}
}
(2)客户端代码#include
#pragmacomment(lib,"ws2_32.lib")voidmain()
{
WORDwVersionRequested;
WSADATAwsaData;//WSAata 用来存储系统传回的关于WinSocket的资料。
interr;
wVersionRequested=MAKEWORD(1,1);
err=WSAStartup(wVersionRequested,&wsaData);if(err!
=0)
{
return;
}
if(LOBYTE(wsaData.wVersion)!
=1||HIBYTE(wsaData.wVersion)!
=1)
{
WSACleanup();return;
}
SOCKETsockClient=socket(AF_INET,SOCK_STREAM,0);
//AF_INET..tcp连接,初始化连接与端口号SOCKADDR_INaddrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
//本机地址,服务器在本机开启addrSrv.sin_family=AF_INET;addrSrv.sin_port=htons(6000);// 设置端口号
connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));// 连接服务器charrecvBuf[50];
recv(sockClient,recvBuf,50,0);//接受数据
printf("%s\n",recvBuf);send(sockClient,"hello",strlen("hello")+1,0);// 发送数据closesocket(sockClient);//关闭连接
WSACleanup();
}
二、运行结果:
三、主要结构体、命令、函数声明及作用
对于一些主要的类、函数代码,主要通过百度逐步了解它们的功能。
以服务器端代码为例,每一段代码作用大致如下:
首先声明一个WORD变量,WSADATA这个结构被用来存储被WSAStartup函数调
用后返回的WindowsSockets 数据。
它包含Winsock.dll执行的数据。
为了在应用程序当中调用任何一个WinsockAPI函数,首先第一件事情就是必须通过WSAStartup函数完成对Winsock服务的初始化,因此需要调用WSAStartup函数。
该函数的第一个参数指明程序请求使用的Socket版本,其中高位字节指明副版本、低位字节指明主版本;操作系统利用第二个参数返回请求的 Socket的版本信息。
wVersion是WindowsSocketsDLL期望调用者使用的WindowsSockets规范的版本。
高位字节存储副版本号,低位字节存储主版本号,可以用WORDMAKEWORD(BYTE,BYTE)返回这个值,例如:
MAKEWORD(1,1)。
MAKEWORE(1,1)和MAKEWORD(2,2)的区别在于,前
者只能一次接收一次,不能马上发送,而后者能。
SOCKETsocket(intaf,inttype,intprotocol);
应用程序调用socket函数来创建一个能够进行网络通信的套接字。
第一个参数指定应用程序使用的通信协议的协议族,对于TCP/IP协议族,该参数置AF_INET;
第二个参数指定要创建的套接字类型,流套接字类型为SOCK_STREAM、数据报套接字类型为SOCK_DGRAM、原始套接字SOCK_RAW(WinSock接口并不适用某种特定的协议去封装它,而是由程序自行处理数据报以及协议首部);
第三个参数指定应用程序所使用的通信协议。
SOCKADDR_IN数据结构用做bind、connect、recvfrom、sendto等函数的参数,指明地址信息。
但一般编程中并不直接针对此数据结构操作,而是使用另一个与sockaddr等价的数据结构。
sockaddr_in和sockaddr是并列的结构,指向sockaddr_in的结构体的指针也可以指向sockaddr 的结构体,并代替它。
也就是说,可以使用sockaddr_in建立所需要的信息,然后用进行类型转换就可以了
htonl()将主机的无符号长整形数转换成网络字节顺序。
函数返回一个网络字节顺序的值。
INADDR_ANY是指定地址为0.0.0.0的地址,这个地址事实上表示不确定地址,或“所有地址”、“任意地址”。
一般来说,在各个系统中均定义成为0值。
htons()将一个无符号短整型数值转换为网络字节序,即大端模式(big-endian)
返回值为TCP/IP网络字节顺序.
bind的函数声明
intPASCALFARbind(SOCKETs,conststructsockaddrFAR*name,s:
标识一未捆绑套接口的描述字。
name:
赋予套接口的地址。
sockaddr结构定义如下:
structsockaddr{
u_shortsa_family;
charsa_data[14]; };namelen:
name名字的长度。
将一本地地址与一套接口捆绑。
本函数适用于未连接的数据报或流类套接口,在connect()或listen()调用前使用。
当用socket()创建套接口后,它便存在于一个名字空间(地址族)中,但并未赋名。
bind()函数通过给一个未命名套接口分配一个本地名字来为套接口建立本地捆绑(主机地址/端口号)。
listen在套接字函数中表示让一个套接字处于监听到来的连接请求的状态,它的功能是把一个本地地址与套接字关联。
参数s是一个已绑定未被连接的套接字描述符;backlog是连接请求队列(queueofpendingconnections)的最大长度(一般由2到4)。
用SOMAXCONN则由系统确定。
Accept()将从连接请求队列中获得连接信息,创建新的套接字,并返回该套接字的文件描述符。
新创建的套接字用于服务器与客户机的通信,而原来的套接字仍
然处于监听状态。
函数声明intaccept(intsockfd,void*addr,int*addrlen); 参数sockfd:
监听的套接字描述符;addr:
指向结构体sockaddr的指针;addrlen:
addr参数指向的内存空间的长度。
Sprintf()将字串格式化命令。
sprintf是个变参函数,格式要注意,否则会引起程序
崩溃
inet_ntoa()
本函数将一个用in参数所表示的Internet地址结构转换成以“.”间隔的诸如“a.b.c.d”的字符串形式。
请注意inet_ntoa()返回的字符串存放在WINDOWS套接口实现所分配的内存中。
应用程序不应假设该内存是如何分配的。
在同一个线程的下一个WINDOWS套接口调用前,数据将保证是有效。
Send()函数声明:
ssize_tsend(ints,constvoid*msg,size_tlen,intflags); 第一个参数指定发送端套接字描述符;第二个参数指明一个存放应用程式要发送数据的缓冲区;第三个参数指明实际要发送的数据的字节数;第四个参数一般置0。
Recv()函数从一个套接口接收数据。
intPASCALFARrecv(SOCKETs,charFAR*buf,intlen,intflags); 参数s:
一个标识已连接套接口的描述字;buf:
用于接收数据的缓冲区;len:
缓冲区长度;flags:
指定调用方式。
四、实验心得总结
刚开始对于socket编程完全不了解,出于畏惧心理,本来想就此罢休,写一篇论文就行。
不过周围的同学很热心的帮助了我,给我了一些socket编程的参考资料,上面的讲解很清楚,再加上我对这个很好奇,也想体验一下,所以才有了接下去的工
作。
在网络编程中最常用的方案便是Client/Server(客户机/服务器)模型。
在这种方案中客户应用程序向服务器程序请求服务。
一个服务程序通常在一个众所周知的地址监听对服务的请求,也就是说,服务进程一直处于休眠状态,直到一个客户向这个服
务的地址提出了连接请求。
在这个时刻,服务程序被 "惊醒"并且为客户提供服务-对客户的请求作出适当的反应。
现在的 Winsock已经基本上实现了与协议无关,我们可以使用Winsock来调用多种协议的功能,但较常使用的是TCP/IP协议。
Socket实际
在计算机中提供了一个通信端口,可以通过这个端口与任何一个具有Socket接口的计算机通信。
应用程序在网络上传输,接收的信息都通过这个Socket接口来实现。
在VC中进行WINSOCK的API编程开发的时候,需要在项目中使用下面的三个文件,
否则会出现编译错误。
1.WINSOCK.H:
这是WINSOCKAPI的头文件,需要包含在项目中。
2.WSOCK32.LIB:
WINSOCKAPI 连接库文件。
在使用中,一定要把它作为项目的非缺省的连接库包含到项目文件中去。
3.WINSOCK.DLL:
WINSOCK的动态连接库,位于WINDOWS的安装目录下。
服务器端编程主要步骤:
1:
加载套接字库,创建套接字(WSAStartup()/socket());
2:
绑定套接字到一个IP地址和一个端口上(bind());
3:
将套接字设置为监听模式等待连接请求(listen());
4:
请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept());
5:
用返回的套接字和客户端进行通信(send()/recv());
6:
返回,等待另一连接请求;
7:
关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup())。
客户端编程的步骤:
1:
加载套接字库,创建套接字(WSAStartup()/socket());
2:
向服务器发出连接请求(connect());
3:
和服务器端进行通信(send()/recv());
4:
关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup())。
我目前对于程序的理解和应用还是很浅的,不过这次我想自己的目的已经达到了,通过体验socket接口编程,进一步加深了对于计算机通信的理解,也对这门课有了更浓厚的兴趣。
下一步准备借阅相关书籍,通过串口编程实现局域网的界面化聊天功能。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 计算机网络 socket 编程 实验 报告