收藏 分享(赏)

linux网络编程.docx

上传人:无敌 文档编号:697526 上传时间:2018-04-18 格式:DOCX 页数:40 大小:40.82KB
下载 相关 举报
linux网络编程.docx_第1页
第1页 / 共40页
linux网络编程.docx_第2页
第2页 / 共40页
linux网络编程.docx_第3页
第3页 / 共40页
linux网络编程.docx_第4页
第4页 / 共40页
linux网络编程.docx_第5页
第5页 / 共40页
点击查看更多>>
资源描述

1、1. Linux 网络知识介绍1.1 客户端程序和服务端程序 网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的-客户端和服务器端. 网络程序是先有服务器程序启动,等待客户端的程序运行并建立连接.一般的来说是服务端的程序 在一个端口上监听,直到有一个客户端的程序发来了请求. 1.2 常用的命令 由于网络程序是有两个部分组成,所以在调试的时候比较麻烦,为此我们有必要知道一些常用的网络命令 netstat 命令 netstat 是用来显示网络的连接,路由表和接口统计等网络的信息.netstat 有许多的选项 我们常用的选项是 -an 用来显示详细的网络状态.至于其它的选项我们可以使用

2、帮助手册获得详细的情况. telnet telnet 是一个用来远程控制的程序,但是我们完全可以用这个程序来调试我们的服务端程序的. 比如我们的服务器程序在监听 8888 端口,我们可以用 telnet localhost 8888 来查看服务端的状况. 1.3 TCP/UDP 介绍 TCP(Transfer Control Protocol)传输控制协议是一种面向连接的协议 ,当我们的网络程序使用 这个协议的时候,网络可以保证我们的客户端和服务端的连接是可靠的,安全的. UDP(User Datagram Protocol)用户数据报协议是一种非面向连接的协议,这种协议并不能保证我们 的网络

3、程序的连接是可靠的,所以我们现在编写的程序一般是采用 TCP 协议的. 2. 初等网络函数介绍(TCP)Linux 系统是通过提供套接字(socket)来进行网络编程的.网络程序通过 socket 和其它几个函数的调用,会返回一个 通讯的文件描述符,我们可以将这个描述符看成普通的文件的描述符来操作,这就是 linux 的设备无关性的 好处.我们可以通过向描述符读写操作实现网络之间的数据交流 . 2.1 socket int socket(int domain, int type,int protocol) domain:说明我们网络程序所在的主机采用的通讯协族(AF_UNIX 和 AF_INE

4、T 等). AF_UNIX只能够用于单一的 Unix 系统进程间通信,而 AF_INET 是针对 Internet 的,因而可以允许在远程 主机之间通信(当我们 man socket 时发现 domain 可选项是 PF_*而不是 AF_*,因为 glibc 是posix 的实现 所以用 PF 代替了 AF,不过我们都可以使用的). type:我们网络程序所采用的通讯协议(SOCK_STREAM,SOCK_DGRAM 等) SOCK_STREAM表明我们用的是 TCP 协议,这样会提供按顺序的,可靠,双向 ,面向连接的比特流. SOCK_DGRAM 表明我们用的是 UDP 协议,这样只会提供定

5、长的,不可靠,无连接的通信. protocol:由于我们指定了 type,所以这个地方我们一般只要用 0 来代替就可以了 socket 为网络通讯做基本的准备.成功时返回文件描述符,失败时返回-1,看 errno 可知道出错的详细情况. 2.2 bind int bind(int sockfd, struct sockaddr *my_addr, int addrlen) sockfd:是由 socket 调用返回的文件描述符 . addrlen:是 sockaddr 结构的长度. my_addr:是一个指向 sockaddr 的指针. 在中有 sockaddr 的定义 struct sock

6、addr unisgned short as_family; char sa_data14; ; 不过由于系统的兼容性,我们一般不用这个头文件,而使用另外一个结构(struct sockaddr_in) 来代替.在中有 sockaddr_in 的定义 struct sockaddr_in unsigned short sin_family; unsigned short int sin_port; struct in_addr sin_addr; unsigned char sin_zero8; 我们主要使用 Internet 所以 sin_family 一般为 AF_INET,sin_add

7、r 设置为 INADDR_ANY 表示可以 和任何的主机通信,sin_port 是我们要监听的端口号.sin_zero8是用来填充的. bind 将本地的端口同 socket 返回的文件描述符捆绑在一起.成功是返回 0,失败的情况和 socket 一样 2.3 listen int listen(int sockfd,int backlog) sockfd:是 bind 后的文件描述符. backlog:设置请求排队的最大长度.当有多个客户端程序和服务端相连时, 使用这个表示可以介绍的排队长度. listen 函数将 bind 的文件描述符变为监听套接字 .返回的情况和 bind 一样. 2.

8、4 acceptint accept(int sockfd, struct sockaddr *addr,int *addrlen) sockfd:是 listen 后的文件描述符 . addr,addrlen 是用来给客户端的程序填写的,服务器端只要传递指针就可以了. bind,listen 和accept 是服务器端用的函数,accept 调用时,服务器端的程序会一直阻塞到有一个 客户程序发出了连接. accept 成功时返回最后的服务器端的文件描述符,这个时候服务器端可以向该描述符写信息了. 失败时返回-1 2.5 connect int connect(int sockfd, stru

9、ct sockaddr * serv_addr,int addrlen) sockfd:socket 返回的文件描述符. serv_addr:储存了服务器端的连接信息.其中 sin_add 是服务端的地址 addrlen:serv_addr 的长度 connect 函数是客户端用来同服务端连接的.成功时返回 0,sockfd 是同服务端通讯的文件描述符 失败时返回-1. 2.6 实例 服务器端程序 /* 服务器程序 (server.c) */ #include #include #include #include #include #include #include #include int

10、main(int argc, char *argv) int sockfd,new_fd; struct sockaddr_in server_addr; struct sockaddr_in client_addr; int sin_size,portnumber; char hello=“Hello! Are You Fine?n“; if(argc!=2) fprintf(stderr,“Usage:%s portnumberan“,argv0); exit(1); if(portnumber=atoi(argv1)h_addr); /* 客户程序发起连接请求 */ if(connect

11、(sockfd,(struct sockaddr *)( exit(1); /* 连接成功了 */ if(nbytes=read(sockfd,buffer,1024)=-1) fprintf(stderr,“Read Error:%sn“,strerror(errno); exit(1); buffernbytes=0; printf(“I have received:%sn“,buffer); /* 结束通讯 */ close(sockfd); exit(0); MakeFile 这里我们使用 GNU 的 make 实用程序来编译. 关于 make 的详细说明见 Make 使用介绍 # M

12、akefile # all:server client server:server.c gcc $ -o $ client:client.c gcc $ -o $ 运行 make 后会产生两个程序 server(服务器端) 和 client(客户端) 先运行./server portnumber /* 主机的正式名称 */ char *h_aliases; /* 主机的别名 */ int h_addrtype; /* 主机的地址类型 AF_INET*/ int h_length; /* 主机的地址长度 对于 IP4 是 4 字节 32 位*/ char *h_addr_list; /* 主机的

13、 IP 地址列表 */ #define h_addr h_addr_list0 /* 主机的第一个 IP 地址*/ gethostbyname 可以将机器名(如 )转换为一个结构指针.在这个结构里面储存了域名的信息 gethostbyaddr 可以将一个 32 位的 IP 地址(C0A80001)转换为结构指针. 这两个函数失败时返回 NULL 且设置 h_errno 错误变量,调用 h_strerror()可以得到详细的出错信息 3.3 字符串的 IP 和 32 位的 IP 转换. 在网络上面我们用的 IP 都是数字加点(192.168.0.1)构成的 , 而在 struct in_addr

14、 结构中用的是 32位的 IP, 我们上面那个 32 位 IP(C0A80001)是的 192.168.0.1 为了转换我们可以使用下面两个函数 int inet_aton(const char *cp,struct in_addr *inp) char *inet_ntoa(struct in_addr in) 函数里面 a 代表 ascii n 代表 network.第一个函数表示将 a.b.c.d 的 IP 转换为 32 位的 IP,存储在 inp 指针里面.第二个是将 32 位 IP 转换为 a.b.c.d 的格式. 3.4 服务信息函数 在网络程序里面我们有时候需要知道端口.IP 和

15、服务信息.这个时候我们可以使用以下几个函数 int getsockname(int sockfd,struct sockaddr *localaddr,int *addrlen) int getpeername(int sockfd,struct sockaddr *peeraddr, int *addrlen) struct servent *getservbyname(const char *servname,const char *protoname) struct servent *getservbyport(int port,const char *protoname) struct

16、 servent char *s_name; /* 正式服务名 */ char *s_aliases; /* 别名列表 */ int s_port; /* 端口号 */ char *s_proto; /* 使用的协议 */ 一般我们很少用这几个函数.对应客户端,当我们要得到连接的端口号时在 connect 调用成功后使用可得到 系统分配的端口号 .对于服务端,我们用 INADDR_ANY 填充后,为了得到连接的 IP 我们可以在 accept 调用成功后 使用而得到 IP 地址. 在网络上有许多的默认端口和服务,比如端口 21 对 ftp80 对应 WWW.为了得到指定的端口号的服务 我们可以调用第四个函数,相反为了得到端口号可以调用第三个函数. 3.5 一个例子 #include #include #include #include #include int main(int argc ,char *argv) struct sockaddr_in addr; struct hostent *host; char *alias;

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

当前位置:首页 > 企业管理 > 经营企划

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报