无连接的套接字通信第16章无连接的套接字通信gCC16.14.c输入下面的命令,对这个程序添加可执行权限。chmod +x a, out输入下面的命令,运行这个程序/out程序的运行结果如下所示。a socket was crcatcdsocket number: 3connec=: Invalid argument12.12取得 socket状态函数 getsockopt可以取得一个 socket的参数。这个函数的使用方法如下所示int getsockopt(int s, int level, int optnanme, void* optval, socklen t* optlen)i在参数列表中,s表示已经建立 socket的编号, level代表需要设置的网络层,一般设成SOL_ SOCKET来表示 socket层,参数 optname表示需要获取的选项,可以没置成下面这些值。SO DEBUG:打开或关闭排错模式SO REUSEADDR:允许在bind函数中本地IP地址可重复使用。SO TYPE:返回 socket形态。SO ERROR:返回 socket已发生的错误原因· SO DONTROUTE:送出的数据包不要利用路由设备来传输。SO BROADCAST:使用播方式传送SO SNDBUF:设置送出的奢存区大小。SO RCVBUH:设置接收的暂存区大小。SO KEEPALIVE:定期确定连线是否终止。SO OOBINLINE:当接收到OOB数据时会马上送至标准输入设备。SO LINGER:确保数据可以安全可靠传送出去。参数 optval是取得的某个参数的返冋值指针,程序的返冋值会保存在这个指针指向的变量中,参数 optlen表示 opial的内存长度。函数如果执行成功则返回0,反之返回-1。这个函数可能发生下面这些错误。EBADE:参数s不是合法的 socket代码。ENOTSOCK:参数s为一打开文件的编号,而不是一个 socketENOPROTOOPT:参数 optname指定的选项不正确EFAULT:参数 optval指针指向的内存空间无法读取。在使用这个函数之前,需要在程序中的最前面包含下面的头文件。#include#include下面的程序是用 getsockopt函数来读取一个 socket的参数的实例。39完全手册Linux系统下C程序开发详解±nc1deinclude#include/*包含头文件。*int nain(int s;定义相关的变量。/int val, lcnlen- sizeof(int)i/*长度。*/f((s= socket( AF TNFT, SOCK STREAM,0))<0)/*立一个套接字。perror("connect")ie⊥se建立成功printf("a socket was created. \n")printf( sacket numltsockopt(a, SOL SOCKE, SO TYPE,&va1,1n);/*取得套接字的一个信息。*/perror("socket: )i/*输出错误。*/print=("optval =d\n", val);/*输出结果。*/getsackopt(100, SOL SOCKE, SC TYPE,&ya1,&len);/用错误的方法取得一个信息。*/perror(socket m输入下面的命令,编译这个程序。6.16.C输入下面的命令,对这个程序添加可执行权限。chmod +x01t输入下面的命令,运行这个程序。程序的运行结果如下所示。cdsocket number: 3cket: Bad file descriptor第16章无连接的套接字通信口12.13设置 socket状态函数 setsockopt可以设置一个 socket的状态,这个函数的使用方法如下所示。int setscckopt (int s, int level, int optnarme, const void optval, socklent xoptlen)在参数列表中,s表示已经打开的 socket。参数 level代表欲设置的网络层,一般设成SOL SOCKET以存取 socket层,参数 optname, optval, optlen的含义与121.2节中的这些参数作用相同。如果函数设置 socket成功则返回0,若有错误则返回-1。这个函数可能发生下面列出的错误,可以用erno捕获已经发牛的错误· EBADE:参数s不是合法的 socket代码。● ENOTSOCK:参数s为打开文件的编号,而不是个 socketENOPROTOOPT:参数 optname指定的选项不正确。· EFAULT:参数 optval指针指向的内存空间无法读取。使用这个函数前,需要在程序的最前面包含卜面的头文件include include 卜面的实例使用了 setsockopt函数来设置一个 socket的状态。参数 pinane设置成SO TYPE,表示设置这个 socket的状态,设置的值为includeinclude⊥nc1de/大包含头文件。*/int main()int si大定义相关的变量。大/nt val=llensizeof(int)if((s socket(AF INET, SOCK STREAM, 0))<0)大建立一个套接字。*perror( connect")it(1);套接字建立成功。printf("a socket was created.\n")iprintf("socket number: c\n",s)ii=setsockopt(s, SOL SoCKET, SC TYPE, &val, len)i大设置套接字的一个参数。*/if("i--0")/*判断结果情况。*/359完全手册Linux系统下C程序开发详解printf("set socket ok.\n "printf("set socket error.\n ")isetsockopt(100, SOL SOCKET, SO TYPE,&va1,1en);/*用错诙的方法设置一个套接perror ("socket)i/*输出错误。输入下面的命令,编译这个稈序输入下面的命令,对这个程序添加可执行权限chmod+×a.0ut输入下血的命令,运行这个程序。程序的运行结果如下所示。a socket was crcatcdsocket number: 3· set socket oksocket: Bad file descriptor122无连接的套接字通信所谓无连接的套接字通信,指的是使用UDP协议进行信息传输。使用这种办议进行通信吋,两个计算机之前没有建立连接的过程。需要处理的内容只是扣信息发送到另个计算机这种通信的方式比较简单。本节将讲述这种无连接的UDP通信。口1221工作流程无套接字的通信不需要建立起客广机与服务器之间的连接,因此在程序中没有建立连接的过程。进行通信之前,需要建立网终套接字。服务器需要绑定一个端口,在这个端口上监听接收到的信息、。客户机需要设置远程IP和端口,需要传递的信息需要发送到这个IP和端口上。客户机和服务器的交互过程可用图12-1来表示。第16章无连接的套接字通信服务器客户枳创建 socketsocket()socket绑定端口bindobindo连接一个指定的汁算机和端口读取接收到的信息 recvfromsandton发送信息发送信息[ rccvfrom(读取接收到的信息图12-1无连接的套接字通信口1221信息发送函数 sendto函数 sendto可以通过一个已经建立的套接字,将一段信息发送到另一个程序的套接字中。这个函数的使用方法如下所示。int sendto( int s, void msg, int lcn, uns-gned int flaga, struct sockaddrtc int olen )i在参数列表中,s表示已经建立好的 socket(在使用UDP协议时,不需要进行计算机连接的操作),msg表示需要发送的字符串,len表示发送字符串的长度,参数fags一般设0,其他可能的数值如下所示MSG OOB:传送的数据以out- of-band送出。MSG DONTROUTE:取消路由衣查询。MSG DONTWAIT:设置为不可阻断传输MSG NOSIGNAL:此传输不愿被 SIGPIPE信号中断参数 sockaddr是一个表示套接字的结构体。这个结构体的定义如下所示这个结构体的定义方法如下所示struct socketaddr inunsigned short int sin famnilyint16 t sstruct in addr sin addrunsigned char sin zero[8li这个结构体的成员与作用如下所示sin family:与 sockaddr结构体中的 sa family相同。sin port:套接字使用的端口号。sin addr:需要访问的IP地止。· Sin zero:未使用的字段,填充为0。在这一结构体中, in addr也是一个结构体,定义方法如下所示。作用是保存一个IP地址。3599完全手册Linux系统下C程序开发详解struct in addruint32 t s addr在程序中,需要设置这个结构体每一个成员的值。参数 tolen是 sockaddr结构体的长度,这一长度可用 sizeof函数来取得。这个结构体会把 socket用指定的 socke传送给对方主机。如果传送成功,则返回传送字符的个数。传送失败则返回-1。传送失败时,错误原因保存在crmo中,可能发生的错误如下所示。● EBADE:参数s不是一个正常的 socket oEFAULT:参数中的指针指向无法读取的内存空间WNOTSOCK:s为一文件描述词,不是一个 socketEINTR:被其他信号所中断。· EAGAIN:此动作会令进程阻断ENOBUFS:系统的缓冲内存不足EINVAL:传给系统调用的参数不正确。使用 sendto函数发送信息之前,需要在程序中包含下面的头文件include sya/typcs.h>include sys/socket.h>[1222信息接收函数 recvfrom数 recvfrom可以从一个 socket中接收其他主机发送到来的信息。这个函数的使用方法如下所示int recvfrom(int s, void *buf, int len, unsigned int flags sockaddr *from r intAfrcmlen)i在参数列表中,s表小一个已经建立一的网络套接字,buf表小接收到的信息保存到的内存地址,Len表示可以保存信息的butf内存长度,fags一般设0,其他可能的设置如下所示MSG OOB:接收以out- of-band送出的数据MSG PEEK:返回来的数据不从系统内删除,如果再调用 reco会返回相同的数据内MSG WAITALL:强迫接收到len大小的数据后才能返回,除非有错误或信号产生。MSG NOSIGNAL:此操作不愿被 SIGPIPE信号中断参数from长示IP地址与端∏等信息。 fromlen表示 sockaddr的长度,这个值可以用 sizeof函数来取得。这个函数调用成功,则返回接收到的宇符数。失败则返回-1,错误原因存于erno中。叫能发生的错误如下所示。EBADE:参数s不是一个正确的 socket.EFAULT:参数中的指针可能指向了无法读取的内存空间。ENOTSOCK:参数s是文件措述词,而不是一个 socket360第16章无连接的套接字通信· EINTR:被其他信号所中断。EAGAIN:此动作会令进程阻断。ENOBUFS:系统的缓冲内存不足。ENOMEM:核心内存不足EINVAL:传给系统调用的参数不正确。使用 recaro函数接收数据前,需要在程序的最前面包含下面的头文件include #:Ide 123无连接的套接字通信实例上一节讲述了无连接的套接字通信原理和相关函数,本节将使用这些函数编写无连接的IDP套接字信息程序。在信息传输时,需要冇服务器端与客户端。服务器处于监听状态,接收到客户端发送的信息以后会返回一定的信息。客户端会主动向服务器发送信息。12.31无连接套接字通信客户端本节将讲述无连接套接字通信的客户端。这个程序的主要内容是,建立一个套接字,然后从键盘读取一个字符串用 sendto函数将这个字符串发送到服务器,然后接收服务器发送回的信息。在实际编稈时,客户机与服务器是在同一个计算机上的。可以使用127.0.0.1这个IP地址衣示本地计算机,这样和访问远程计算机的效果是相同的。include *include include #⊥nC1de< unistd.h>#⊥nC1de#⊥nc1deincl dc include /包含相关的头文件。*define REMOT三彐ORT4567/+定义表示端口号的常量。x#defi: e REMOt三工P"127.0.0.1/+定义表示表二P的常量。xint main(int argc, char *argv[l)nt s,len定义相关的变量kaddr in addchar msg [256]i定义一个数组发送与接收数据。*/int i=0ct(AF INET, SOCK DG/建立一个ack输出错误,*/9完全手册Linux系统下C程序开发详解exit(l)ie⊥se输出提示信息。★/printf(" socked id: d \n", s)printf("remote ip: s \n", REMOTEIP);printf( romote port: d \n, REMOTEPORT)ist个:c大长度Izero(&addr, sizeof(addr))i/*空间地址结构体所在的内存空间。★/addr.si- fanily=AF INeT;/填充地址与端口的信息。xaddr. sin port=tons(REMCTEPORT);端口。大/addr. sin addr. 2 addr-inct addr(remOtely)i/*循环。*/zero(msg, sizeof(rsg))i/*清空msc所在的内存。*1en=read(SDIN彐ILEN○,nsg, sizeof(msg):/*接收信息。*/sendto(s, msg, len,0, &addr, addr len/大发送信息。大printf("\iNput mcssagc: s n", m.sg)i/*输出结果。+/ecvfronm (s, msg, sizeof(msg),0,&addr, addr len);/*这是接收到的信息。*printf("Bd: ",i)i/*输出计数。大1++;/*计数自加。printf("Received Message: % s \n", Imsg);/这是服务器返回的信息。*/输入下面的命令,编译这个程序。需要加-o参数指定一个输出文件名。gcc 1817.c -o udpcli输入下面的命令,对这个稈序添加可执行权限。chmod +x udpcl1232无连接套接字通信服务器本节将讲述无连接套接字通信的服务器。內络传输的功能需要计算机上的多个程序才能完成数据通信。上一节编写程序发送的信息,需要有一个服务器程序米接收和处理。在服务器程序中,主要是使用 recvfrom函数从套接字中接收传入的信息。对信息进行处理以后,用 sendto函数发回段信息。服务器程序的代码如下所t⊥nc1dc< stdio.h>⊥nc⊥ae< netinet/in.h>include ⊥nc1deinclude #include /包含相关的头文件。大36