嵌入式linux_c基础17_第1页
嵌入式linux_c基础17_第2页
嵌入式linux_c基础17_第3页
嵌入式linux_c基础17_第4页
嵌入式linux_c基础17_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、:l.socket网络编程1 网络编程1.1网络常识1.2 c语言的网络编程socket13本机网络编程1.3.1月艮务器?犒的编程步骤1)创建一个socket (套接字,对于网络来说包括ip和端口号xsocket ()函数:2)准备通信地址(3个结构体,只需要记住一个)struct sockaddr.;只用来做参数类型,不会使用里面的成员;实际应用,sockaddr不会使用,只是做一个类型出现;本地通信用sockaddr_un ,网络通信用sockadd3 )绑定socket和通信地址bind ()函数4 )通信,使用文件操作函数即可read , write5 )关闭socket描述符,cl

2、ose函数1.3.2户端的编程步骤1)创建一个socket (套接字,对于网络来说包括ip和端口号xsocket ()函数:2)准备通信地址(3个结构体,只需要记住一个)struct sockaddr.;只用来做参数类型,不会使用里面的成员;实际应用,sockaddr不会使用,只是做一个类型出现;本地通信用sockaddr_un ,网络通信用sockaddr_in本地通信:#in clude<sys/un.h>struct sockaddr_unint sun_family;指定协议簇,与socket函数的domain 致即可 char sun_path ;/本地的socket文件

3、名(带路径);网络通信:#in clude<netinet/i n.h>struct sockadd_inint sin_family;协议簇,与socket函数中的domain 致即可;short sin_port;端口号struct in_addr sin_addr;ip 地址的结构体3 )绑定socket和通信地址connect ()函数4 )通信,使用文件操作函数即可read , write5 )关闭socket描述符,close函数注意:客户端和服务器端交互时,一个如果是写,另外一个必须读。而且次数必须对应 上。如服务器端是:读读写,客户端必须是:写写读。否则就会有三种可

4、能:卡住,报 错,正常(但实际已经异常)1.4网络编程对一形式步骤和本机通信基本相同,但地址应选择sockaddrn网络编程时,通信地址需要借助两个转换函数:htons (端口号)一把本机格式转换成网络格式;htons ()函数功能:网络通信时本地w网路端口转换。格式:#include <arpa/inet.h>uint32_t htonl(uint32_t hostlong);/本机转网络,unsigned long 型uintl6_t htons(uintl6_t hostshort);/本机转网络,unsigned short 型uint32_t ntohl(uint32_t

5、 netlong);/网络转本机,unsigned long 型uintl6_t ntohs(uintl6_t netshort);网络转本机,unsigned short 型注意:一个参数,端口号;返回值:返回转换后的端口值(本地转网络(home to net) /网络转本地(net to home) inet_addr(ip地址)一把点分十进制的字符串转换成16进制的整数;inet.addr ()函数功能:将点分十进制的ip地址字符串转换成为整形数据。格式:#include <sys/socket.h>#inelude <netinet/in.h>#include

6、<arpa/inet.h>in.addrj inet_addr(const char *cp);注意:一个参数,点分十进制ip地址字符串:返回值:返回整数,十六进制的ip地址。* 冈 幺夂%嗝不呈 月艮言镒* *#in clude<stdio.h>#incl ude<stdlib.h>#include<sys/socket.h>#incl udev un istd.h>#in clude<netinet/in.h>#in clude<arpa/i net.h>int main()获取socket描述符int sock

7、fd=socket(pfjnet/sock_dgram/0);if(-l=sockfd)perror("sockfdm);exit(-l);准备通信脱struct sockaddr_in addr;addr.sin_family=pf_inet;端口选择1024-48xxxx,注意需要本地和网络的格式转换addr.sin_port= htons(2222);/ip地址的格式转换,将字符串形式的ip转换成十六进制整数addr.sin_addr.s_addr=inet_addr(" 192.16831.130");int res=bind(sockfd/(struct

8、 sockaddr*)&addr,sizeof(addr);if(-l= = res)perror("bindm);exit(-l); char buf1024=;int len=read(sockfd,butsizeof(buf);printf(n 读到 t%s,%d 字节n;buf len);close(sockfd);return 0; 幺各 木呈* *#include<stdio.h>#incl ude<stdlib.h># include<sys/socket.h>#in clude< un istd.h>#incl

9、ude <netinet/in.h>#include<arpa/i net.h>int main()获取socket描述符int sockfd=socket(pfjnetzsock_dgramro);if(-l=sockfd)perror("sockfd");exit(-l);准备通信賊struct sockaddr_in addr;addr.sin_family=pf_inet;端口选择102牛48xxxx,注意需要本地和网络的格式转换addr.sin_port= hton s(2222);/ip地址的格式转换,将字符串形式的ip转换成十六进制整数

10、addr.sin_addr.s_addr=inet_addr("192.168.31.130");int res=connect(sockfd,(struct sockaddr*)&addcsizeof(addr);if(-l= = res)perror("bind");exit(-l);printf("正在连接服务器.rt);int len=write(sockfd,"helloh,5);close(sockfd); return 0;1.5网络编程一对多形式tcp协议:是一个有连接的协议(基于连接的协议),在整个交互过程中

11、,客户端和服务器要随时保持连接,如同打电话;udp协议:是一个无连接协议,在整个交互过程中无需保持连接,像发短信一样。tcp效率上t隣交低,占用资源大(随时保持连接),但tcp可以保证数据的正确和完整,能重发一切错误数据;udp效率比较高,占用资源小,但udp不保证数据的正确和完整,不会重发错误数据(程序员可以自行弥补tcp编程步骤:服务器端:1. socket (),参数type必须使用 sock_stream ;2. 准备通信地址,sockaddr_in ;3绑定 bind();4.监听客户端r listen ()函数;listen ()函数功能:监听客户端的连接请求。格式:#includ

12、e <sys/types.h>#inelude <sys/socket.h>int listen(int sockfd, int backlog);注意:第一个参数:socket描述符,依据tcp编程步骤,是第一步的socket描述符;第二个参数:队列的最大长度。服务器一次处理只会一个请求,当有多个客户端同时申请时, 则先来的先服务,其他的将会被放进一个队列进行等待,当前一个处理完成之后,再根据请求的先后顺序 依次处理,但是每次处理都要调用重新accept函数建立新的连接。这个参数就是设置这个队列的最大等待 数量;返回值:成功返回0 ,失败返回-1 ,同时设置errno

13、o5.等待客户端的连接(会阻塞),accept ()函数,返回新的socket描述符;accept ()函数功能:响应客户端的网络请求。格式:#include <sys/types.h>#inelude <sys/socket.h>int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);注意:第一个参数:tcp网络编程中第一步产生的socket描述符;第二个参数:一个结构体的指针,存放连接请求连接的客户端的地址,端口等信息;第三个参数:存放第二个参数的结构体的大小的变量地址。这是一个传入传出参数

14、,先传入 addr的大小,函数执行后传出真实接收到的addr的大小(一般情况下是一样的);返回值:成功一个全新的socket描述符,失败返回-1 ,同时设置errnoo6. 使用新的socket描述符进行数据交互;7. close ( x客户端的编程步骤和一对一的网络编程没有变化,但type要设置为sock_stream注意:第一步的socket描述符只负责客户端的连接,与客户端的交互由第五步产生的socket描述符负责*tcp 网幺各通佇服务器端*#incl ude<stdio.h>#incl ude<stdlibh>#in clude<sys/socket.h

15、>#include<neti net/in.h>#in clude<arpa/i neth>#in clude<u nistdh>int main()1获取socket描述符int sockfd=socket(pfjnet/sock_stream/0);if(-l=sockfd)perror(hsocketw);exit(-l);2淮备网络地址struct sockaddrjn addr;addr.sin_family=pf_inet;addr.sin_port=htons(2222);addr.sin_addr.s_addr=inet_addr(&q

16、uot;192.168.31.130");3绑定int resbindcsockfdxstruct sockaddr*)&addr;sizeof(aclcir);if(-l= = res)perror("bind");exit(-l);printf("bind successfullyn");4监听res=listen(sockfd,100);if(-l= = res)perror("listen");exit(-l);准备accept函数的第二个参数和第三个参数struct sockaddr_in from;soc

17、klen_t len二sizeof(from);5使用accept连接客户端prin廿("begin acceptn");int sfd=accept(sockfd,(struct sockaddr*)&addr;&len);if(-l=sfd)perror("accept");exit(-l);/5.1使用inet.ntoa函数将十六进制的ip地址转换成点分十进制,结构体之需要写到sin_addr即可char*cip=inet_ntoa(from.sin_addr);printf("end acceptrt);printf(&

18、quot;%s 连接了本服务器 n;cip);6数据交互char buf256=;read(sfd,buf,sizeof(buf);printf("%sn:buf);write(sfd, "welcome",7);7.关闭socket描述符close(sockfd);close(sfd);return 0;* 冈 幺夂%嗝#呈 户茹*:*:* *#incl ude<stdio.h>#in clude<stdlib.h>#in clude<sys/socket.h>#in clude< un istd.h>#in el

19、ude <netinet/in.h>#include<arpa/i net.h> int main()获取socket描述符int sockfd=socket(pf_inetzsock_stream,0);if(-l=sockfd)perror("sockfd");exit(-l);准备通信賊struct sockaddr_in addr;addr.sin_family=pf_inet;端口选择102牛48xxxx,注意需要本地和网络的格式转换addr.sin_port= hton s(2222);/ip地址的格式转换,将字符串形式的ip转换成十六进

20、制整数addr.sin_addr.s_addr=inet_addr("192.168.31.130");int res=connect(sockfd,(struct sockaddr*)&addr,sizeof(addr);if(-l= = res)perror("c onn ect");exit(-l);char buf256=;printf("正在连接服务器int len=write(sockfd,"hello",5);read(sockfd,butsizeof(buf);printf("%snbuf)

21、;close(sockfd);return 0;*tcp网络通信,服务器端,实现多个客户端访问*# include<stdio.h>#include<stdlib.h>#in c i u d e < sy s/soc ket. h >#in clude<netinet/i n.h>#incl udevarpa/i net.h>#incl ude< un istd.h>#in clude<sig nal.h>使用信号关闭服务器int sockfd;void sig_fun(int signum)close(sockfd

22、);printf("服务器已经关闭rf); exit(o);int main()/使用信号处理,关闭服务器signal(sigint,sig_fun);1获取socket描述符 sockfd=socket(pfjnet,sock_stream/0); if(-l=sockfd)perror(nsocket");exit(-l);2淮备网络地址struct sockaddr_in addr;addr.sin_family=pf_inet;addr.sin_port=htons(2222);addr.sin_addr.s_addr=inet_addr("192.168

23、.31.130");3绑定int res=bind(sockfd,(struct sockaddr*)&addr,sizeof(addr);讦(-l= = res)perror("bind");exit(-l);printf("bind successfullyn");4监听res=listen(sockfd,100);if(-l= = res)perror("listenm);exit(-l);实现多个客户端的连接,但这些客户端不能同时与服务器端进行信息交互;若要实现同时的信息交 互,则属于多进程并行处理,运用多进程或者多线

24、程解决问题。while(l)准备accept函数的第二个参数和第三个参数struct sockaddr_in from;socklen_t len=sizeof(from);5.使用accept连接客户端printf("begin acceptrt);int sfd=accept(sockfd,(struct sockaddr*)&addr,&len);if(-l=sfd)perror("accept");exit(-l);/5.1使用inet_ntoa函数将十六进制的ip地址转换成点分十进制,结构体之需要写到sin.addr 即可char*cip

25、=inet_ntoa(from.sin_addr);printf("end acceptn");printf("%s 连接了本服务器 n",cip);6数据交互char buf256=;read(sfd,buf,sizeof(buf);printf("%sn;buf);write(sfd, "welcome"/);7.关闭socket描述符close(sfd);return 0;代码并行的解决方案:多进程或者多线程。*tcp网络通信,服务器端,实现多个客户端访问,并且并行处理,同时响应*十*#include<stdio

26、.h>#in clude<stdlib.h># i n clude< sys/s ocket.h>#incl udevneti net/in.h>#incl udevarpa/i neth>#incl udevu nistclh>#in clude<stri ng.h>#include<sig nal.h>int sockfd;void sig_fun(int signum)close(sockfd);printf("服务器已经关闭n");exit(o);int main()使用信号处理,关闭服务器 s

27、ignal(sigint,sig_fun);1.获取socket描述符sockfd=socket(pfjnet,sock_stream,0);if(-l=sockfd)perror("socket");exit(-l);2准备网络地址struct sockaddr_in addr;addr.sin_family=pf_inet;addr.sin_port=ht on s(2222);addr.sin_addr.s_addr=inet_addr("192.168.1.49");3绑定int res=bind(sockfd,(struct sockaddr*

28、)&addr,sizeof(addr);if(-l= = res)perrorcbind1');exit(-l);printf("bind successfullyn");4监听,若有多个客户端请求,则放入队列中res=listen(sockfd,100);if(-l= = res)perror("listen");exit(-l);while循环处理请求队列中的客户端请求队列,每处理一个请求就要调用一次accept函数准备accept函数的第二个参数和第三个参数struct sockaddr_in from;socklen_t len=

29、sizeof(from);5.使用accept连接客户端printf("begin acceptrt);int sfd=accept(sockfd,(struct sockaddr*)&from,&len);只要客户端请求队列中有请求,则不 会阻塞;if(-l=sfd)perror("accept");exit(-l);创建子进程专门和客户端进行信息交互,而父进程不进行信息交互。只进行客户端请求的响应。 pid_t pid=fork();if(0= = pid)char*cip=inet_ntoa(from.sin_addr);printf(&qu

30、ot;end acceptrt);printf("%s 连接了本服务器n”,cip);char buf256=;while针对一个客户端反复进行进行交互read(sfd,buf,sizeof(buf);printf("%sn;buf);if(!strcmp(buf" bye")break;write(sfd,buf,strlen(buf)+l);close(sfd);exit(o);return 0;udp编程一无连接的协议服务器端server :l.socket z type 要用 sock_dgram ;2. 准备通信地址,与tcp样;3. bind

31、 ();4数据交互;5.close ();客服端client:l.socket z type 要用 sock_dgram ;2准备通信地址,与tpc样;3数据交互;udp专用读写函数sendto函数recvfrom 函数4. close ();注:1.udp的客户端一般不需要用connect函数进行连接。但udp协议也可以建立 连接,比如:qq在传送文件时。2解决地址被占用问题的方法:int reuseaddr=l;setsockopt ( sockfd f sol_socket,so_reuseaddr,&reuseaddr f sizeof(reuseaddr);卄* 网幺各编程

32、udp 通彳主月艮务立湍*#incl ude<stdio.h>#in clude<stdlib.h>#in clude<sys/socket.h>#in clude< un istd.h>#in elude <netinet/in.h>#include<arpa/i net.h> int main()获取socket描述符int sockfd=socket(pf_inet,sock_dgram,0);if(-l=sockfd)perrorc'sockfd"); exit(-l);准备通信賊struct s

33、ockaddr_in addr;addr.sin_family=pf_inet;端口选择102牛48xxxx,注意需要本地和网络的格式转换 addr.sin_port= hton s(2222);/ip地址的格式转换,将字符串形式的ip转换成十六进制整数addr.sin_addr.s_addr=inet_addr("192.168.1.49");int res=bind(sockfd,(struct sockaddr*)&addr,sizeof(addr);讦(-l= = res)perror(nbind");exit(-l);char buf1024=;struct sockaddr_in from;socklen_t len=sizeof(from);res=recvfrom(sockfd,bu(sizeof(buf)/0,(struct sockaddr*)&from,&len);讦(-l= = res)pe r ro r(" rec vf ro m"); exit(-l);res=sendto(sockfd,"welcome&

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论