ImageVerifierCode 换一换
格式:DOCX , 页数:23 ,大小:756.07KB ,
资源ID:7775138      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bingdoc.com/d-7775138.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(socket编程实验报告Word文档下载推荐.docx)为本站会员(b****3)主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(发送邮件至service@bingdoc.com或直接QQ联系客服),我们立即给予删除!

socket编程实验报告Word文档下载推荐.docx

1、 在server端,server首先启动,调用socket( )创建套接字,然后调用bind( )绑定server的地址(IP+port),调用recvfrom( )等待接收数据。在client端,先调用socket()创建套接字,调用sendto( )向server发送数据。server接收到client发来数据后,调用sendto( )向client发送应答数据,client调用recv接收server发来的应答数据。数据传输结束,server和client通过调用close( )关闭套接字。 原理图如图1。图1 UDP通信原理图1.2 实现方案和实验结果1.2.1 方案1:Linux上两

2、个进程间的通信方案1实现方案server端:首先调用socket函数创建一个socket,然后调用bind函数将其与本机地址以及一个本地端口号绑定,用recvfrom函数接收到一个client端的消息后,用printf打印出来,server从标准输入设备中取得一行字符串后,调用sendto函数发送给client端。最后用close关闭该socket。client机端:首先调用socket函数创建一个socket,初始化server地址及端口号(实际上就是本机),从标准输入设备中取得字符串,用sendto传送给server端,然后用recv函数接收server端发来的字符串,用printf打印出

3、来。源代码见附录。方案1实验结果server和client通信截图图2 UDPserver图3 UDPClient1.2.2 方案2:Windows主机(client)和Linux虚拟机(server)之间的进程通信 方案2实现方案利用Vmware station的Linux虚拟机与Windows本机之间的局域网进行进程间通信,Linux虚拟机作为server,Windows本机作为client。除了Windows使用winsock函数库之外,实现方案与方案1类似,但要注意client端初始化的server地址虽然与方案1相同,但此时已不再是本机地址,而是局域网中Linux虚拟机的IP地址,相

4、当于模拟了不同机器间的进程通信。方案2实验结果图4 server图5 client2 基于TCP的Socket编程2.1 实验原理:基于TCP协议的面向C/S的工作流程在server端,server首先启动,调用socket( )创建套接字;然后调用bind( ) 绑定server的地址(IP+port);再调用listen( )让server做好侦听准备,并规定好请求队列长度,然后server进入阻塞状态,等待client的连接请求;最后通过accept( )来接收连接请求,并获得client的地址。当accpet接收到一个client发来的connet请求时,将生成一个新的socket,用

5、于传输数据。在client端,client在创建套接字并指定client的socket地址,然后就调用connect( )和server建立连接。一旦连接建立成功,client和server之间就可以通过调用recv和send来接收和发送数据。一旦数据传输结束,server和client通过调用close( )来关闭套接字。原理图如图6。图62.2 实现方案首先调用socket函数创建一个Socket,然后调用bind函数将其与本机地址以及一个本地端口号绑定,然后调用listen在相应的socket上监听client,当accpet接收到一个client发来的connet请求时,将生成一个新的

6、socket,用于传输数据。Recv( )接收到一个client端的消息后,server从标准输入设备中取得一行字符串,调用send()发送给client端。client端:首先调用socket函数创建一个Socket,初始化server地址及端口号,然后调用connet请求连接监听server。通过server端accept函数生成的新socket,调用send函数向server端发送从标准输入设备中取得的字符串,然后用recv接收server端发来的字符串。最后用close()关闭该数据传输socket和监听socket。2.3 实验结果图7 TCPserver图8 TCPserver三、

7、讨论与心得记得助教第一节课讲socket的时候,我听得云里雾里的,只觉得是个很神奇的可以实现进程间通信的类似于接口的东西。印象深刻的是他举的那个打电话的例子,描述得很直观形象。老师说让我们做这个实验主要是为了体会TCP/IP的原理,并不要求应用做得多么高端,比如图形界面什么的。我觉得,我既然是网络工程专业的,就更应该学好计算机网络这门课,更好地了解socket编程。抱着这种决心,我开始了学习。于是我先去网上找了有关socket编程的讲解,觉得一篇一切皆socket的帖子写得很易懂,对于各个函数的功能有了初步的了解。操作系统的课程也有一个做shell命令解释器的实验,与socket编程实验基本是

8、先后进行的。在做了shell,熟悉了“一切皆文件”的linux以及编译、运行的方法之后,感觉跟好理解,更好入手了。我先对照着一切皆socket的帖子看老师给的资料附录一中的示例一、二,也就是TCP。原来socket()是用来创建一个,然后返回值是这个socket的描述符,很类似与文件描述符。bind()是用来为这个socket绑定server的IP+port地址,当然绑定之前要先对server的地址进行初始化。listen()的作用是监听client的请求,第二个参数规定了这个刚刚创建的socket可以接受几个client的服务请求。一旦accept()了一个client的请求,就获得了这个c

9、lient的地址,这真是个很神奇的东东啊!操作系统就会又给它分配了一个socket,也就是accept的返回值,用来传输数据。也就是说,TCP开了2个socket,一个用来监听子进程,一个用来传输数据。accept之后就可以自由发挥,开始进行网络I/0了!我们运行程序时可以看到的功能就是在下面的部分实现的。再往下的收发函数,read()/write(),recv()/send(),readv()/writev(),recvfrom()/sendto(),recvmsg()/sendmsg()什么的,就是用数据传输的socket了,而非监听的socket了。关于收发函数,我又上网查了一下资料。拿

10、recv()/send()举例,其实recv只是把TCP协议传过来的数据copy到我们自己定义的buf里去。而recv所做的把发送缓冲区里的数据被协议发送到接收缓冲区这个过程对于编程用户来讲是不可见的,而recv只是把接收缓冲区里的数据copy出来而已。Send与之类似。从这个层面上讲,socket是一个TCP协议提供的接口服务,用传输层的协议干应用层想干的事。最后不要忘记用close()关掉创建的两个socket。此外,我大概理解了TCP的三次握手在函数中的体现,要传三个报文,如图1。图9 TCP的三次握手建立连接看懂、理解了代码后,我把代码拷了进去,调试成功后,看到了server会把cli

11、ent发过来的数据再返回去,我觉得这个没什么意义,就想改编它,让server也可以通过输入回答client。于是就又定义了一个buf3,用gets函数接受标准输入到buf3里,然后用把buf3的内容发给client。一个偶然的发现让我理解了TCP所谓的四次握手释放过程。当我把client关掉时,server就自动关掉了。当client首先调用close主动关闭连接,这时TCP发送一个FIN M;另一端接收到FIN M之后,执行被动关闭,对这个FIN进行确认。它的接收也作为文件结束符传递给server的应用程序,因为FIN的接收意味着server的应用进程在相应的连接上再也接收不到额外数据;一段

12、时间之后,server上接收到文件结束符的应用进程调用close关闭它的socket。这导致它的TCP也发送一个FIN N;接收到这个FIN的源发送端TCP对它进行确认。这样每个方向上都有一个FIN和ACK。图10 socket中发送的TCP四次握手释放调通了TCP之后,我去尝试UDP。其实这顺序是反了的,因为UDP貌似更简单一些,可是因为TCP有现成的代码,所以就先理解了TCP。之后去查UDP的资料,直观上感觉除了创建socket()时定义的协议不同外,就是少了一些函数,少用了一个socket。对于server来讲,bind()之后,不用再listen和accept了,就是不用监听了,直接用

13、这个socket来进行数据传输就可以了。于是我就想当然地觉得下面进行网络I/O的收发函数应该是差不多的,就直接用了刚才在TCP里用的recv和send。对于client来讲,我也是直接用的这两个函数。然后怎么都传不了数据,实现不了通信。于是我仔细比较了几个函数的参数,发现recvfrom比recv多了2个参数,后来理解了一下,这是因为TCP在accept时就为与之通信的每个进程分配了一个socket用于数据传输,也就是说对于server的每个client都有一个专门的进程与其进行通信。而UDP没有开另外的进程,也就是没有创建新的socket,所以server的多个client是共用这一个soc

14、ket的,可以说是多路复用了。为了辨别多个client,server需要client的地址(ip+port)来接受和发送,于是就要用recvfrom多出来的2个参数,即client的地址和地址长度。这也就同时解释了为什么UDP只创建一个socket就够了。对于UDP的client端来说,只需要在发送数据的时候用sendto来表明server的地址,在接收数据时就不需要的了,因为只有一个server,不需要标记了。因为我是在虚拟机上进行的以上实验,我就想利用主机和虚拟机之间的局域网来建立连接,进行进程通信。虽然操作系统不同,socket库不同,但是只要使用了相同的协议(我选择的是UDP)就可以进

15、行通信。于是我又去学习了Winsock的相关知识,实现了不同系统间的通信。我觉得虽然Windows和Linux的socket使用总体上差不多,但是Winsock的一些准备(我觉得比较冗余)复杂一点。四、源代码【UDP方案1】Server端源码:/udpService: #include sys/socket.hnetinet/in.hstdio.herrno.hstdlib.hstrings.hunistd.hstring.hctype.h #define PORT 7000 int main(void) int sockfd,pktlen; char buf300,buf1300; stru

16、ct sockaddr_in server,client;sockfd=socket(AF_INET,SOCK_DGRAM,0); memset (char *)&server, sizeof(server), 0); /将已开辟内存空间 server 的全部字节的值设为值0.类似于bzero server.sin_family = AF_INET; server.sin_port = htons(PORT);/端口号 server.sin_addr.s_addr = INADDR_ANY;/设置网络地址,INADDR_ANY表示机器的IP地址bind(sockfd,(struct socka

17、ddr *)&server,sizeof(struct sockaddr_in); for (;) /*recv接受client发送的数据,recv函数仅仅是copy数据,真正的接收数据是协议来完成的),第一个参数指定接收端套接字描述符;第二个参数指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据;第三个参数指明buf的长度recv函数返回其实际copy的字节数*/ int l=sizeof(struct sockaddr_in); pktlen = recvfrom (sockfd, buf, sizeof (buf), 0,(struct sockaddr_in *)&client,

18、&l); if (pktlen = 0) break; printf (Received line: %sn, buf);Enter a line: ); fgets(buf1,300,stdin);/*并不是send把ns的发送缓冲中的数据传到连接的另一端的,而是协议传的,send仅仅是把buf中的数据copy到ns的发送缓冲区的剩余空间里返回实际copy的字节数*/sendto (sockfd, buf1,sizeof(buf1), 0,(struct sockaddr_in*)&client,l);close(sockfd); Client端源码:/udpClient:arpa/inet

19、.h #define MAX_SIZE 1024 #define HOST_ADDR 192.168.145.137 int main(int argc,char *argv) int sockfd,buflen; char buf1300,buf2300; struct sockaddr_in server; server.sin_family=AF_INET; server.sin_addr.s_addr = inet_addr (HOST_ADDR); for(;) gets (buf1);/从stdin流中读取字符串,直至接受到换行符 buflen = strlen (buf1); i

20、f (buflen = 0)sendto(sockfd, buf1, buflen + 1, 0,(struct sockaddr *)&server,sizeof(server);recv(sockfd, buf2, sizeof (buf2), 0); printf(, buf2); close(sockfd); return 0;【UDP方案2】Linux server端源码同方案1Windows client端源码:/客户端#include #define INVALID_VALUE32 0xFFFF#pragma comment(lib, ws2_32.lib/客户端主函数开始voi

21、d main() int err = INVALID_VALUE32; WORD ver; WSADATA wsaData; /定义版本号 ver = MAKEWORD(2, 2); /* 版本号为2.2版本,1.1也可以 */ /* 接下来初始化 */ err = WSAStartup(ver, &wsaData); if (err != 0) /* 检查socket是否初始化成功 */ return; if (2 != (LOBYTE(wsaData.wVersion) | (2 != HIBYTE(wsaData.wVersion) WSACleanup(); /* 版本错误则清楚导入的

22、DLL */ /* 开始socket的主体部分:创建socket */ SOCKET sockClient = socket(AF_INET, SOCK_DGRAM, 0); /* AF_INET表示网络使用的范围internetwork: UDP, TCP, etc, SOCK_STREAM表示使用的是TCP SOCK_DGRAM 表示使用的是UDP类型 */ SOCKADDR_IN addrSrv; addrSrv.sin_addr.S_un.S_addr = inet_addr( / 这里设置为服务器的IP地址,由于我在自己的机器上面写的,所以写回环地址了 addrSrv.sin_fam

23、ily = AF_INET; addrSrv.sin_port = htons(7000); /* 端口随便只要不跟系统冲突就行 */ /* 定义几个缓冲区,也是接受和发送的,设置成100即可 */ char recvbuf100; char sendbuf100; int len=sizeof(SOCKADDR); /* 下面进入死循环 */ while (1) printf(nEnter a line:n gets(sendbuf); sendto(sockClient, sendbuf, strlen(sendbuf)+1, 0, (SOCKADDR *)&addrSrv, len);

24、int recvnum = recvfrom(sockClient, recvbuf, 100, 0, (SOCKADDR *)&addrSrv, &len); recvbufrecvnum = 0; /* 将接收到的数据存入数据缓冲区,以便显示 */Receive a line %s, recvbuf); /* 最后将socket清空 */ closesocket(sockClient); WSACleanup(); return;【TCP】#define PORT 7000main ()struct sockaddr_in client, server;/ 客户端地址信息 本机地址信息in

25、t s, ns, namelen, pktlen;/s:监听socket ns:数据传输socket namelen:client的地址长度 pktlen:传送数据的字节数char buf400;char buf3200;s=socket(AF_INET, SOCK_STREAM, 0); /创建连接的SOCKET,s为socket描述符/ 初始化服务器地址memset (char *)&server.sin_family = AF_INET;server.sin_port = htons(PORT);server.sin_addr.s_addr = INADDR_ANY;/server需要在

26、listen之前绑定一个大家都知道的地址,就是刚刚初始化好的ip+端口号bind(s, (struct sockaddr *)&server, sizeof(server);listen(s,1);/侦听客户端请求,i为socket可以排队链接的最大个数/*接受client请求,s为server的描述符(即监听socket描述符),第二个参数即指针client的协议地址,第三个参数代表地址长度返回值ns是一个全新的描述符,是数据传输socket,代表与返回客户的tcp连接*/namelen = sizeof (client);ns = accept (s, (struct sockaddr *)&client, &namelen);/开始进行网络I/Ofor (;第三个参

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2