试题五
请阅读以下说明和Socfort程序,将应填 __(n)__ 处的字句写在答题纸的对应栏内。
【说明】
网络应用的基本模型是客户机/服务器模型,这是一个不对称的编程模型,通信的双方扮演不同的角色:客户机和服务器。
以下是一个简单的客户机程序(服务器程序略),其工作过程非常简单:客户机与服务器建立连接后,接收服务器向客户机返回的一条消息。
程序中用到了两种结构 hostent 与 sockaddr_in:
hostent类型的结构定义
struct hostent { char *h_name ; //主机的正式名称
char * *h_aliases ; //别名列表
int h_addrtype ; //主机地址类型:AF_XXX
lnt H_length; //主机地址长度:4 字节(32 位)
char * *h_addr_list;//主机 IP 地址列表 }
#define h_addr h_addr_list[0]
sockaddr_in 类型的结构定义,sockaddr_in 是通用套接字结构 sockaddr 在 TCP/IP 协议下
的结构重定义,为 TCP/IP 套接字地址结构。
Struct sockaddrin {
short int sin_family ;//地址类型 AF_XXX,其中 AF_INET 为 TCP/IP 专用
unsigned short int sin_port; //端口号
struct in_addr sin_addr; //Internet 地址
//端口号以及 Internet 地址使用的是网络字节顺序,需要通过函数 htons 转换
}
struct iN_addr {
_u32 s_addr; //类型为 unsignel_long
}
程序中使用到了多个函数:struct hostent * gethostbyname( const char *hostname);
函数 gethostbyname 查询指定的域名地址对应的 IP 地址,返回一个 hostent结构的指针,如果不成功返回 NULL。
int_socket(int domain,int_type,int protocol);
函数 socket 创建一个套接字描述符,如果失败返回 -1。domain 为地址类型,type为套接字类型,本题中为 SOCK_STREAM ;protocol 指定协议,本题中为 0 。
int connect( int sockfd,struct sockaddr *servaddr, int addrlen);
函数connect与服务器建立一个连接,成功返回 0,失败返回- 1。servaddr 为远程服务器的套接字地址,包括服务器的 IP 地址和端口号;addrlen 为地址的长度。
int read( int fd,char *buf,int len);
int write( int fd,char *buf,int len);
函数read和write从套接字读和写数据,成功返回数据量大小,否则返回 -1。buf 指定数据缓冲区,len 指定接收或发送的数据量大小。
【socket程序】
//程序中引用的头文件略
#define PORT 3490
//定义端口号为 3490
int main( int argc,char *argv[] )
{ int sockfd,nbytes; //套接字描述符、读入缓冲区的字节数
char buf[1024]; //缓冲区
struct hostent *he; //主机信息类型
struct sockaddr_in srvaddr;//Internet套接字结构
if ( __(1)__ )
{ perror( "调用参数为零,请输入服务器的主机名!\n" ); exit(1);}
if ( __(2)__ ) //如果通过主机名没有获得对应的主机信息就提示用户
{ perror("无法通过主机名获得主机信息!\n" ); exit(1);}
if ( __(3)__ ) //在无法创建套接字时,提示用户
{ perror("无法创建套按字!\n" ); exit(1);}
bzero( &srvaddr,sizeof(srvaddr));//置空 srvaddr
srvaddr,sin_family = AF_INET;
srvaddr,sin_port:__(4)__ ;srvaddr.sin_addr:__(5)__ ;
//设置套接字结构的各项信息,其中的地址来自于域名查询后的 hp 变量
if ( connect( sockfd,__(n)__ ,sizeof( struct sockaddr)) == -1 )
{ perror("连接失败!\n" ); exit(1);}
//连接服务器,如果失败则提示用户
if (( nbytes = read ( sockfd,buf,MAXDATASIZE)) == -1 )
{ perror( "读失败!\n" ); exit(1);}
//从套容接字中读出数据
buf[nbytes] = '\0';
printf("读到的内容:%s",buf) ;
close( sockfd) ;
//打印数据并关闭套接字
}
责任编辑:cyth