第八章 网络编程
8.1 概述
本章介绍UNIX网络编程-即网间进程通讯。UNIX网间进程通讯是通过通讯应用程序接口(API)来实现的。目前,在UNIX环境下最流行的API是伯克利套接字(Socket)和UNIX System V的传送层接口(TLI)。我们主要介绍套接字API。
Socket通过域 (domain)来划分所支持的协议, 目前支持的域有: UNIX域支持在UNIX系统中的进程通讯、Internet域支持TCP/IP协议等。 Socket的实现者试图以UNIX文件的操作语义来模拟进程通讯的操作,其操作方式与文件操作有许多对应。例如,socket( )调用可近似的看成是open( )调用,调用返回的文件描述字作为其他调用的第一参数;socket 中也使用了read 和write 调用,其语法和语义与文件操作中的read 和 write 调用几乎完全一致。Socket中的调用 bind、connect和accept 显示了建立网络连接的方法。 如图8-1所示。Socket进程通讯仍使用Client/Server 模型,建立连接时,Client 和 Server 所做的工作是不对称的。
8.2 套接字编程接口说明
下面结合实例来说明套接字编程接口。
·socket系统调用 实现套接字的分配,调用格式如下: #include <sys/types.h> #include <sys/socket.h> int socket(int domain, int type, int protocol); 其中:参数domain是一个常量,它规定区域,常用的是AF_INET;参数type是一个常量,规定套接字的类型,可以是SOCK_STREAM,SOCK_DGRAM或SOCK_RAW;protocol是一个常量,规定所用的协议。此参数仅在type为SOCK_RAW时有意义,其他情况下忽略。此参数为0时选择默认协议。
·bind系统调用 当应用程序获得套接字后,可以使用bind()调用为套接字联系一个独一无二的名字,如下面一段代码: struct sockaddr_in serverAddress ; memset( (char *)&serverAddress , 0 , sizeof(struct sockaddr_in) ) ; serverAddress.sin_family =AF_INET ; serverAddress.sin_addr.s_addr =inet_addr("202.96.6.15") ; serverAddress.sin_port = htons( 7000); if( bind( sockfd , &serverAddress ,sizeof( struct sockaddr_in ) ) ==-1 ) { perror( "bind error" ) ; exit( 2 ) ; }
这段代码说明SERVER程序运行在IP地址202.96.6.15,端口号为7000上。Bind调用之后相当于将自己的服务地址公布出去。 bind的调用格式如下: #include <sys/types.h> #include <sys/socket.h> int bind (int s, const struct sockaddr *name, int namelen);
其中:参数s是socket调用返回的文件描述字,参数name是指向结构sockaddr的指针,参数namelen指定结构的大小。
·listen系统调用 在bind调用之后,SERVER程序使用listen调用来准备接收来自CLIENT的连接。listen的调用格式如下: #include <sys/types.h> #include <sys/socket.h> int listen (int s, int backlog); 其中:参数s是socket调用返回的文件描述字,参数backlog指定最大连接数。
·accept系统调用 在listen调用之后,SERVER程序使用accept调用实际接收来自CLIENT的连接请求。accept的调用格式如下: #include <sys/types.h> #include <sys/socket.h> int accept (int s, struct sockaddr *addr, int *addrlen); 其中:参数s是socket调用返回的文件描述字,参数addr指向结构sockaddr,负责读入CLIENT端的相应信息。参数addrlen指出addr对应结构的长度。
·connect系统调用 在CLIENT方,调用socket之后,就可使用connect调用向SERVER初始化一个连接请求。如下面的代码: struct sockaddr_in serverAddress ; memset( (char *)&serverAddress , 0 , sizeof(struct sockaddr_in) ) ; serverAddress.sin_family =AF_INET ; serverAddress.sin_addr.s_addr =inet_addr("202.96.6.15") ; serverAddress.sin_port = htons( 7000); if( connect( sockfd , &serverAddress ,sizeof( struct sockaddr_in ) ) ==-1 ) { perror( "bind error" ) ; exit( 2 ) ; } 这段代码完成了向运行在IP地址202.96.6.15,端口号为7000上的SERVER程序建立连接。 connect的调用格式如下: #include <sys/types.h> #include <sys/socket.h> int connect (int s, const struct sockaddr *name, int namelen); 其中:参数s是socket调用返回的文件描述字,参数name是指向结构sockaddr的指针,参数namelen指定结构的大小。
·read/write/close系统调用 与普通文件操作类似。
(本文已被浏览 4848 次)
|
|