Linux下Socket编程.docx

上传人:夺命阿水 文档编号:1466275 上传时间:2024-06-29 格式:DOCX 页数:36 大小:89.42KB
返回 下载 相关 举报
Linux下Socket编程.docx_第1页
第1页 / 共36页
Linux下Socket编程.docx_第2页
第2页 / 共36页
Linux下Socket编程.docx_第3页
第3页 / 共36页
Linux下Socket编程.docx_第4页
第4页 / 共36页
Linux下Socket编程.docx_第5页
第5页 / 共36页
点击查看更多>>
资源描述

《Linux下Socket编程.docx》由会员分享,可在线阅读,更多相关《Linux下Socket编程.docx(36页珍藏版)》请在课桌文档上搜索。

1、端以及面对连接SOCkel的服务端通过调用bind函数来配践本地信息。Bind函数将SOCket及本机上的一个端口相关联,随后你就可以在该端口监听服务恳求。Bind函数原型为:inibind(intsockd,structsockaddr*myaddr,intUddrIen);Sockfd是调用SOCket函数返回的SOCkel描述符,my_addr是一个指向包含有本机IP地址及端口号等信息的sockaddr类型的指针:addrlen常被设置为sizeof(structSOCkaddr)OstructSOCkaddr结构类型是用来保存SoCket信息的:structsockaddrunsign

2、edshortsa_famiIy:*地址族,FXXX*/charsa-data14:*14字节的协议地址*/):safamily一般为AFINET,代表Internet(TCP/IP)地址族:Sadalu则包含该SOCkel的IP地址和端口号。另外还有种结构类型:structSOCkaddJinshortintsinamiIy;/地址族*/unsignedshortintsin_port;/端口号*/structin_addrsin_addr:*IP地址*/unsignedcharsin-zero8;*填充0以保持及StrUCtSoCkaddr同样大小/;这个结构更便利运用。Sin_Zero用

3、来将SoCkaddrin结构填充到及StrUCtSoCkaddr同样的长度,可以用bzerc。或memset()函数将其置为零.指向SOCkaddrin的指针和指向SoCkUddr的指针可以相互转换,这意味若假如一个函数所需参数类型是sockaddr时,你可以在函数调用的时候将一个指向sockaddrin的指针转换为指向sockaddr的指针:或者相反。运用bind函数时,可以用下面的赋值实现自动获得本机IP地址和随机获得一个没有被占用的端口号:my_addr.sin_port-0;/*系统随机选择一个未被运用的端口号*/my_addr.sin_addr.s_addr=1NADDR_ANY:*

4、填入本机IP地址*/通过将my_addr.Sin_POrt置为0,函数会自动为你选择一个未占用的湍口来运用.同样,通过将myaddr.sinaddr.saddr置为INADDRANY,系统会自动城入本机IP地址。用意在运用bind函数是须要将sin_port和Sin_addr转换成为网络字节优先依次;而sinaddr则不须要转换。计算机数据存储有两种字节优先依次:高位字节优先和低位字节优先。Internet上数据以高位字节优先依次在网络上传输,所以对于在内部是以低位字节优先方式存储数据的机器,在Internet上传输数据时就须要进行转换,否则就会出现数据不一样。下面是儿个字节依次转换函数: h

5、tonlO:把32位值从主机字节序转换成网络字节序 hlons():把16位值从主机字节序转换成网络字节序ntohl():把32位值从网络字节序转换成主机字节序 ntohs():把16位值从网络字节序转换成主机字节序Bindo函数在胜利被调用时返回0:出现错误时返回并将”皿。置为相应的错误号。须要留意的是,在调用bind函数时一般不要将端口号置.为小于1024的值,因为1到1024是保留端口号,你可以选择大于1024中的任何一个没有被占用的端口号。连接建立面对连接的客户程序运用Connect函数来配置socket并及远端服务器建立一个TCP连接,其函数原型为:intconnect(intsoc

6、kfd,structsockaddr*servaddr,intaddrlen);Sockfd是socket函数返回的SoCket描述符:serv_addr是包含远端主机IP地址和端口号的指针:addrlen是远端地质结构的长度。Connect函数在出现错误时返回T,并且设置errno为相应的错误码。进行客户端程序设计无须调用bind。,因为这种状况下只需知道目的机器的IP地址,而客户通过哪个湍口及服务器建立连接并不须要关切,SOCket执行体为你的程序自动选择一个未被占用的端口,并通知你的程序数据什么时候到打断口。Connect函数启动和远端主机的干脆连接。只有面对连接的客户程序运用socke

7、t时才须要将此SoCket及远端主机相连。无连接协议从不建立干脆连接.面对连接的服务器也从不启动一个连接,它只是被动的在协议端口监听客户的恳求。1.isten函数使SOCket处于被动的监听模式,并为该socket建立一个输入数据队列,将到达的服务恳求保存在此队列中,直到程序处理它们。int1isten(intsockfd,intbacklog);Sockfd是Socket系统调用返回的socket描述符:backlog指定在恳求队列中允许的最大恳求数,进入的连接恳求将在队列中等待accept。它们(参考下文).BaCkIOg对队列中等待服务的恳求的数目进行了限制,大多数系统缺省值为20。假如

8、一个服务恳求到来时,输入队列已满,该SOCket将拒绝连接恳求,客户将收到一个出错信息。当出现错误时IiStCn函数返回-1,并置相应的erno错误码。accept。函数让服务器接收客户的连接恳求.在建立好输入队列后,服务器就调用accept函数,然后睡眠并等待客户的连接恳求。intaccept(intsockfd,void*addr,int*addrlen):sockfd是被监听的socket描述符,addr通常是一个指向SOCkaddrJn变量的指针,该变砥用来存放提出连接恳求服务的主机的信息(某台主机从某个端口发出该恳求):addrlen通常为一个指向值为SiZeOf(StrUCtSoC

9、kaddr_in)的整型指针变量。出现错误时accept函数返回T并置相应的errno值。首先,当accept函数监视的SOCkel收到连接恳求时,socket执行体将建立一个新的socket,执行体招这个新socket和恳求连接进程的地址联系起来,收到服务恳求的初始socket仍可以接着在以前的SOCket上监听,同时可以在新的socket描述符上进行数据传输操作。数据传输SendO和recv()这两个函数用丁面对连接的socket上进行数据传输“Sendo函数原型为:intsend(intsockfd,constvoid*msg,intIen1intflags);SoCkfd是你想用来传输

10、数据的SOCkCt描述符:msg是个指向要发送数据的指针:1.en是以字节为单位的数据的长度:门ags一般状况下置为0(关丁该参数的用法可参照man手册).Sendo函数返回事实上发送出的字节数,可能会少于你希望发送的数据。在程序中应当将Sendo的返回值及欲发送的字节数进行比较。当Sendo返回值及Ien不兀配时,应当对这种状况进行处理。char*nsg=Hello!”;inilen,bytessent;Icn=Strlen(msg);bytes_sent-send(sockfd,msg,len,0):recv()函数原至为:intrecv(intsockfd,void*buf,intIcn

11、1unsignedintflags);SoCkfd是接受数据的SoCkCt描述符:buf是存放接收数据的缓冲区:Icn是缓冲的长度.FIatJS也被置为0。ReCvo返回事实上接收的字节数,当出现错误时,返回T并置相应的errn。值。SendtoO和recvfrom用于在无连接的数据报socket方式下进行数据传输。由于本地socket并没有及远端机器建立连接,所以在发送数据时应指明目的地址。SendlOo函数原型为:intsendto(intsockfdlconstvoid*msg,intIen1unsignedintflags,conststructsockaddr+to,inttolen

12、);该函数比Sendo函数多了两个参数,t。表示日地机的IP地址和端口号信息,而t。Ien经常被赋值为Sizeof(slruclsockuddr).Sendto函数也返回实际发送的数据字节长度或在出现发送错误时返回7。RecvfromO函数原型为:intrecvfrom(intsockfd,void*buf,intIon,unsignedintflags,structsockaddrfrom,int*fromlen);from是一个StrUCtSOCkaddr类型的变量,该变量保存源机的IP地址及端口号。fromIen常置为sizeof(structsockaddr).当recrom()返回时

13、,Cromlen包含实际存入from中的数据字节数。RecvfromO函数返回接收到的字节数或当出现错误时返回T,并置相应的ecn。假如你时数据报socket调用fconnect()函数时,你也可以利用send()和recv()进行数据传输,但该SoCkel仍旧是数据报SoCkeI,并且利用传输层的UDP服务。但在发送或接收数据报时,内核会自动为之加上目地和源地址信息。结束传输当全部的数据操作结束以后,你可以调用ClOSeO函数来释放该SOCke3从而停止在该socket上的任何数据操作:close(sockfd):你也可以调用ShUtdOWn()函数来关闭该sockets该函数允许你只停止在

14、某个方向上的数据传输,而一个方向上的数据传输接着进行.如你可以关闭某SOCket的写操作而允许接着在该SoCkel上接受数据,直至读入全部数据。intshutdown(intsockfd,inthow):SOCkfd是须要关闭的SoCkCt的描述符。参数h。W允许为ShUtdoWn操作选择以下几种方式: O不允许接着接收数据 1不允许接着发送数据 2不允许接着发送和接收数据, 均为允许则调用CloSO()ShIHdCmn在操作胜利时返回0,在出现错误时返回-1并置相应errn。Socket编程实例代码实例中的服务器通过socket连接向客户端发送字符串Hello,youareconnected

15、!”。只要在服务器上运行该服务器软件,在客户端运行客户软件,客户端就会收到该字符串该服务器软件代码如下:SincludeJfinclude件include#includeSincludeSinclude件include#includeWefineSERVPORT3333*服务器监听端口号*/defineBACKl.OG10/*最大同时连接恳求数*/main()(intsockfd,client_fd;/*sock_fd:监听SoCket;CIient_fd:数据传输SoCket/structSoCkaddJinmyaddr;/*本机地址信息*/structSoCkaddJinremoteadd

16、r;/*客户端地址信息*/if(SoCkfd=SockelSF-JNET,SOCKSTREAM,0)=-1)PerrOrrSOCket创建出错!);exit(I);my_addr.sin_family=AF_INET:myaddr.sinporl=htons(SERVIX)RT);myaddr.sin-addr.s_addr=INDDRANY:bzero(myaddr.sin_zero),8):if(bind(sockfd,(structsockaddr*)&my_addr,sizoof(structsockaddr)=-1)perror(,bind出错!);exit(l):if(listen

17、(sockfd,BACK1.OG)=-1)PerrOr(lislen出错!;exit(l);whiIe(I)sinsize=sizeof(structsockaddrin);if(client_fd=accept(sockfd,(structSoCkaddr*)&remote_addr,&sinsize)=-1)PerrOr(accept出错”);continue;Printf(receivedaconnectionfromsn,inct_ntoa(remoteaddr.sinaddr):if(SforkO)*子进程代码段*/if(send(clientfd,Hello,youareconne

18、cted!n,26,O)=1)Perror(send出错!”);close(client-fd);exit(O);close(clientfd):)服务器的工作流程是这样的:首先调用SOCket函数创建个SOCke3然后调用bind函数将其及本机地址以及一个本地湍口号绑定,然后调用IiSIen在相应的SoCkel上监听,当accpel接收到一个连接服务恳求时,将生成一个新的socket,服务器显示该客户机的IP地址,并通过新的SoCket向客户端发送字符串“Hello,youareconnected!*.最终关闭该SoCkCt。代码实例中的fork()函数生成一个子进程来处理数据传输部分,fo

19、rk。语句对石子进程返回的值为0。所以包含fork函数的if语句是子进程代码部分,它及if语句后面的父进程代码部分是并发执行的。客户端程序代码如下:件include#includeSinclude#include力include*includeSincludeSincludedefineSERYPORT3333defineMAXDATASlZEloo*每次最大数据传输量*/main(intargc,char*argv)intsockfd,reevbytes:charbufMAXI)TASIZE:structhostent*hosl:structSOCkaddJinservaddr;if(arg

20、ch_addr);bzero(&(serv_addr.sinzero),8):if(connect(sockfd,(structSoCkUddr*)servaddr,sizeof(structsockaddr)-I)PerrOr(connect出错!”):oxit(l):)if(recvbytes=recv(sockfd,buf,MAXDTASIZE,0)=-1)PerrOr(recv出错!;oxit(l);)bufrecvbytes=,0;Printf(Received:%s*,buf):close(sockfd);)客户端程序首先通过服务蹲域名获得服务器的IP地址,然后创建一个SoCket

21、,调用ConneCt函数及服务冷建立连接,连接胜利之后接收从服务器发送过来的数据,最终关闭SOCkCt。函数gothostbynaIneo是完成域名转换的由于IP地址难以记忆和读写,所以为了便利,人们经常用域名来表示主机,这就须要进行域名和IP地址的转换。函数原型为:structhostent*gethostbyname(constchar*name);函数返回为hosten的结构类型,它的定义如下:structhostontchar*hname;/主机的官方域名*/char*haliases:/*一个以NU1.1.结尾的主机别名数组*/inth-addrtype;/*返回的地址类型,在Int

22、ernet环境下为AFTNET*/inth_length:/*地址的字节长度*/char*haddrlist;/*一个以0结尾的数组,包含该主机的全部地址*/;Mefineh_addrh.addrlist0j/*在h-addrTist中的第个地址*/当goth。Stnameo调用胜利时,返回指向StrUCth。Ssn的指针,当调用失败时返回当调用gethostbyname时,你不能运用Perror。函数来输出钳误信息,而应当运用he门。r()函数来输出。无连卷的客户/服务器程序的在原理上和连接的客户/服务活是样的,两者的区分在于无连接的客户/服务器中的客户一般不须要建立连接,而且在发送接收数据

23、时,须要指定远端机的地址。堵塞和非堵塞堵塞函数在完成其指定的任务以前不允许程序调用另一个函数。例如,程序执行一个读数据的函数调用时,在此函数完成读操作以前将不会执行下一程序语句。当服务器运行到accept语句时,而没有客户连接服务恳求到来,服务港就会停止在accept语句上等待连接服务恳求的到来。这种状况称为堵塞(blocking),而非堵塞操作则可以马上完成.比如,假如你希望服务器仅仅留意检查是否有客户在等待连接,有就接受连接,否则就接若做其他事情,则可以通过将Socket设置为非堵塞方式来实现。非堵塞socket在没有客户在等待时就使accept调用马上返回。#includeinclude

24、sockfd=SOCket(AFNET,SOCK_STREAM,0):fcnt1(sockfd,F_SETF1.O_NONB1.OCK):通过设置SOCket为非堵塞方式,可以实现轮i旷若干SOCkCte当企图从个没有数据等待处理的非堵塞SoCkQt注入数据时,函数将马上返回,返回值为T,并置errn。值为ER0U1.DB1.0CK但是这种轮询”会使CPU处于忙等待方式,从而降低性能,奢侈系统资源。而调用SeIeCtO会有效地解决这个问题,它允许你把进程本身挂起来,而同时使系统内核监听所要求的一组文件描述符的任何活动,只要确认在任何被监控的文件描述符上出现活动,selecl()调用符返回指示该

25、文件描述符已打算好的信息,从而实现了为进程选出随机的改变,而不必由进程本身对输入进行测试而奢侈CPU开销.Select函数原型为:intselect(intnunfds,fd_set*readfds,fdset*writefds,fdset*exceptds,structtimeval*lineut);其中readfds、Writefds、exc。PIfdS分别是被SCIeCt()监视的读、写和异样处理的文件描述符集合.假如你希望确定是否可以从标准输入和某个socket描述符读取数据,你只须要招标准输入的文件描述符0和相应的Sockdtfd加入到readfds集合中:numfds的值是须要检查

26、的号码最高的文件描述符加1.这个例子中numfds的值应为sockfd+1;当select返回时,readfds将被修改,指示某个文件描述符已经打算被读取,你可以通过叩ISSSETo来测试.为了实现fdSel中对应的文件描述符的设置、发位和测忒,它供应了一组宏:FD_ZERO(fd_set*set)-清除一个文件描述符集:FkSET(intfd,fd_set*set)一一将一个文件描述符加入文件描述符集中:FDC1.R(intfd,fdset*set)-将一个文件描述符从文件描述符集中清除;FD_ISSCT(intfd,fd_set*set)试推断是否文件描述符被置位。Timeout参数是个指

27、向structtimeval类型的指针,它可以使SeleCt()在等待timeout长时间后没有文件描述符打算好即返回.structtimeval数据结构为:structtimevalinttvsec:*seconds*/inttv_usec:/microseconds*/I:POP3客户端实例卜.面的代码实例基于POP3的客户协议,及邮件服务渊连接并取回指定用户帐号的邮件。及邮件服务器交互的吩咐存储在字符串数组POPMeSSage中,程序通过个dorhiIe循环依次发送这些吩咐./include才includeJfinclude,include#includeSincludeJfinclud

28、eJfinclude*defineP0P3SERVP0RTHO#defineMAXDTASIZE1096main(intargc,char*argv)intsockfd;structhostent*hosl;structSOCkaddJinSerJaddr;char+POPMessage=“USERusoridrn,PSSPaSSWordrn”,*STATrn*,1.ISTrn”,RETRlrn*,DE1.EIrn*,wQUlTrnNU1.1.):inii1.ength;intiMsg=O;intiEnd=O;charbufMXDATASIZE:if(host=ge1.hoslbyname(,

29、your.server*)=NU1.1.)(Perror(gelhostbynameerror);exit(1):)if(SOCkfd=socket(AlINET,SOCKSTREAM,0)=1)PerrOr(socketeo);exit(1):)serva(ldr.sinfamiIy=AFINET;servaddr.sin_port=htons(P0P3SERVP0RT);servaddr.sinaddr=+(structinaddr*)host-h_addr):bzero(&(servaddr.sinzero),8);if(connect(sockfd,(structsockaddr*)&

30、serv_addr,sizeof(structsockaddr)=-1)PerrOr(connecterror);exit(1);)do(send(sockfd,POIlcssageiMsg,strlen(POPMessagetiMsg),O);printf(*havesent:%s*,1POPMessagetiMsg):ilngth=recv(sockfd,buf+iEnd,sizeof(buf)-iEnd,O):iEnd+=i1.ength;bufiEnd=0;Printf(received:%s,%dn*,1buf1iMsg):iMsg+;while(POPMessagetiMsg);c

31、lose(sockfd):1.inuxISocket编程基础东北高校秦皇岛分校软件中心技术研发部敬茂华1、引言1.inux的兴起可以说是Internet创建的一个奇迹.1.inux作为一个完全开放其原代码的免费的自由软件,兼容了各种UNIX标准(如POSIX、UNlXSySIemY和BSDUNIX等)的多用户、多任务的具有困难内核的操作系统,在中国,随着Internet的普及.批主要以高等院校的学生和ISP的技术人员组成的1.inUX爱好者队伍己经蓬勃成长起来.越来越多的编程爱好者也渐渐酷爱上这个优秀的自由软件。本文介绍了1.irmXF5。CkeI的基本概念和函数调用,2,什么是SoCkelS

32、ocket(套接字)是通过标准的UNlX文件描述符和其它程序通讯的一个方法。每一个套接字都用一个半相关描述:协议,本地地址、本地端口)来表示;一个完整的套接字则用一个相关描述:协议,本地地址、本地端口、远程地址、远程端口,每一个套接字都仃个本地的由操作系统安排的唯的套接字号。3、S。Cket的三种类型(1)流式SOCket(SOCtSTREAM)潦式套接字供应牢靠的、面对连接的通信流:它运用TCP协议,从而保证了数据传输的正确性和依次的。(2)数据报Socket(SoCK_DGRNI)数据报套接字定义了一种无连接的服务,数据通过相互独立的报文进行传输,是无序的,并且不保证牢靠;、无差错。它运用

33、数据报协议U)P(3)原始SoCket原始套接字允许对底房协议如IP或ICMP干脆访问,它功能强大但运用较为不便,主要用于一些协议的开发。4、利用套接字发送数据1、对下流式套接字用系统调用send()来发送数据“2,对于数据报套接字,则须要自己先加一个信息头,然后调用SendIO()函数把数据发送出去。5、1.inux中SOCket的数据结构(1) structsockaddr用于存储套接字地址unsignedshortsa_family;地址类型charsadata14;14字节的协议地址):(2) structSOCkaddr_in/in代表internetshortintsin_fami

34、ly:/internet协议族unsignedshortintsinport;/端口号,必需是网络字节依次structin_addrsinaddr;/internet地址,必需是网络字节依次unsignedcharsin_zero;/添0(和StrUCtSoCkaddr一样大小);(3) structin_addrunsignedlongsaddr:):6、网络字节依次及其转换函数(1)网络字节依次每台机罂内部对变星的字节存储依次不同,而网络传输的数据是肯定要统一依次的.所以对内部字节表示依次及网络字节依次不同的机器,肯定要对数据进行转换,从程序的可移植性要求来讲,就算本机的内部字节表示依次及

35、网络字节依次相同也应当在传输数据以前先调用数据转换函数,以便程序移植到其它机器上后能正确执行。真正转换还是不转换是由系统函数自己来确定的。(2)有关的转换函数* unsignedshortinthtons(unsignedshortinthostshort):主机字节依次转换成网络字节依次,对无符号短型进行操作4byles* unsignedlonginthtonl(unsignedlonginthostlong):主机字节依次转换成网络字节依次,对无符号长型进行操作8byles* unsignedshortintntohs(unsignedshortintnetshort):网络字节依次转换

36、成生机字节依次,对无符号短型进行操作4bytes* unsignedlongintntohl(unsignedlongintnetlong):网络字节依次转换成主机字节依次,对无符号长型进行操作8bytes注:以上函数原型定义在nelinelinh里7, IP地址转换有三个函数将数字点形式表示的字符串IP地址及32位网络字节依次的二进制形式的IP地址进行转换(1) unsignedlongintinetaddr(constchar*cp):该函数把一个用数字和点表示的IP地址的字符串转换成一个无符号长整型,如:structSockaddrininaina.sinaddr.s_addr=inet

37、_addr(202.206.17.10!,)该函数胜利时:返回转换结果:失败时返回常量INADDRNONE,该常量=7,二进制的无符号整数T相当于255.255.255.255,这是一个广播地址,所以在程序中调用inejaddr()时,肯定要人为地对调用失败进行处理。由于该函数不能处理广播地址,所以在程序中应当运用函数inetatonO4(2) intinet_aton(constchar*cp,structinaddr*inp):此函数将字符串形式的IP地址转换成二进制形式的IP地址:胜利时返回1,否则返回0,转换后的IP地址存储在参数inp中。(3) char*inetnloa(struc

38、tin-addrin):将32位二进制形式的IP地址转换为数字点形式的IP地址,结果在函数返回值中返回,返回的是一个指向字符串的指针。8、字节处理函数S。Ckel地址是多字节数据,不是以空字符结尾的,这和C语言中的字符串是不同的。1.inUX供应了两组函数来处理多字节数据,一组以b(byte)开头,是和BSD系统兼容的函数,另一组以mem(内存)开头,是ANSlC供应的函数.以b开头的函数有:(1) voidbzero(void*s,intn):将参数S指定的内存的前n个字节设置为0,通常它用来将套接字地址清0。(2) voidbcopy(constvoid*src,voiddest.intn

39、):从参数SrC指定的内存区域拷贝指定数目的字节内容到参数dest指定的内存区域。(3) intbcmp(constvoid*si.constvoid*s2.intn):比较参数Sl指定的内存区域和参数s2指定的内存区域的前n个字节内容,假如相同则返回0,否则返回非0。注:以上函数的原型定义在Strings.h中.以mcm开头的函数有:(1) void*memset(void*s.intc.size_tn):将参数S指定的内存区域的前n个字节设置为参数c的内容。(2) void*memcpy(void*dest,constvoid*src.SiZe_tn):功能同bcopy().区分:函数bc

40、opy()能处理参数SrC和参数dest所指定的区域有重叠的状况,memcpy()则不能“(4) intmemenip(constvoid*si,constvoid*s2.sizetn):比较参数SI和参数s2指定区域的前n个字节内容,假如相同则返回0,否则返回非0。注:以上函数的原型定义在String.h中。9、基本套接字函数(1)socket()#include#includeintsocket(intdomain,inttype,intprotocol)参数domain指定要创建的套接字的协议族,可以是如下(ft:AFjJNIX/UNIX域协议族,本机的进程间通讯时运用AF_INET/I

41、nternet协议族(TCP/IP)AFSO/ISo协议旗参数type指定套接字类型,可以是如卜值:SOCKSTREAH流套接字,面对连接的和牢靠的通信类型SOCKIXiRAM数据报套接字,非面对连接的和不行靠的通信类型SOCK_RAf原始套接字,只对Insrnet悔议有效,可以用来干脆访问IP协议参数ProtOCol通常设设成0,表示运用默认协议,如IntCrnCt协议族的流套接字运用TCP协议,而数据报套接字运用UDP协议,当套接字是原始套接字类型时,须要指定参数protocol,因为原始套接字对多种协议有效,如ICHP和IGMP等。1.inux系统中创建一个套接字的操作主要是:在内核中创

42、建一个隹接字数据结构,然后返回一个套接字描述符标识这个套接字数据结构。这个套接字数据结构包含连接的各种信息,如对方地址、TCP状态以及发送和接收缓冲区等等,TCP协议依据这个套接字数据结构的内容来限制这条连接.(2)函数ConneCt()includettincludeintconnect(intsockfd,structSockaddr*SerVaddr,intHddrlen)参数sockfd是函数socket返回的套接字描述符:参数SerVaddr指定远程服务器的套接字地址,包括眼务器的IP地址和端口号:参数UddrIen指定这个套接字地址的长度。胜利时返回0,否则返回T,并设置全局变量为

43、以卜任何一种错误类型:ETIMEOUT.Econnrefused.EHOSTUNREACH或ENETUNREACH.在调用函数ConnCCt之前,客户机须要指定服务器进程的套接字地址.客户机般不须耍指定自己的套接字地址(IP地址和端口号),系统会自动从1024至5000的端口号范围内为它选择一个未用的端口号,然后以这个端口号和本机的IP地址填充这个套接字地址。客户机调用函数connect来主动建立连接。这个函数将启动TCP协议的3次握手过程。在建立连接之后或发生错误时函数返回。连接过程可能出现的错误状况有:(1)假如客户机TCP协议没有接收到对它的SYN数据段的确认,函数以错误返回,错误类型为

44、ETIMEOUT。通常TCP协议在发送SYN数据段失败之后,会多次发送SYN数据段,在全部的发送都中学失败之后,函数以错误返ISh注:SYN(synchronize)位:恳求连接。TCP用这种数据段向对方TCP协议恳求建立连接,在这个数据段中,TCP协议将它选择的初始序列号通知对方,并且及对方协议协商最大数据段大小。SYN数据段的序列号为初始序列号,这个SYN数据段能够被确认。当协议接收到对这个数据段的确认之后,建立TCP连接。(2)假如远程TCP协议返回一个RST数据段,函数马上以错误返回,错误类型为ECONNREFUSED。当远程机罂在SYN数据段指定的目的端口号处没有服务进程在等待连接时

45、,远程机器的TCP协议将发送个RST数据段,向客户机报告这个错误。客户机的TCP协议在接收到RST数据段后不再接着发送SYN数据段,函数马上以错误返回。注:RST(resel)位:表示恳求班附连接,当TCP协议接收到一个不能处理的数据段时,向对方TCP协议发送这种数据段,表示这个数据段所标识的连接出现了某种错误,恳求TCP协议将这个连接清除。有3种状况可能导致TCP协议发送RST数据段:(I)SYN数据段指定的目的湍口处没有接收进程在等待:(2)TCP协议想放弃一个已经存在的连接:(3)TCp接收到一个数据段,但是这个数据段所标识的连接不存在。接收到RST数据段的TCP协议马上将这条连接非正常

46、地断开,并向应用程序报告错误。(3)假如客户机的SYN数据段导致某个路由涔产生“目的地不行到达”类里的ICVP消息,函数以错误返回,错误类型为EHOSTUNREACH或ENETUNREACH。通常TCP协议在接收到这个ICVP消息之后,记录这个消息,然后接着几次发送SYN数据段,在全部的发送都告失败之后,TCP协议检查这个IQ(P消息,函数以借误返回。注:ICMP:Internet消息限制怖议。Internel的运行主要是由InCernet的路由器来限制,路由器完成IP数据包的发送和接收,假如发送数据包时发生错误,路由罂运用IcMP协议来报告这些错误。ICMP数据包是封装在IP数据包的数据部分中进行传输的,其格式如下:类型码校验和数据08162431类型:指出IGlP数据包的类型。代码:供应IelP数据包的进一步信息.校验和:供应了对整个ICMP数据包内容的校验和。IeVP数据包主要仃以下类型:(1)目的地不行到达:Z目的主机未运行:B、目的地址不存在:C、路由表中没有目的地址对应的条目,因而路由器无法找到去往日的主机的路由。(2)超时:路由器将接收到的IP数据包的生存时间(TT1.)域减1,假如这

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 在线阅读 > 生活休闲


备案号:宁ICP备20000045号-1

经营许可证:宁B2-20210002

宁公网安备 64010402000986号