软件设计师考试复习指导:socket简要
来源: 考试大 [ 2005-04-27 00:00:00 ] 作者: 责任编辑:冰天使
套接字结构
struct sockaddr_in
{
short int sin_family; //地址类型 AF_XXX(AF_UNIX,AF_INET和AF_NS)
unsigned short int sin_port; //16位端口号
struct in_addr sin_addr; //32位IP地址
char sin_zero[8]; //保留
} //端口号以及 Internet 地址使用的是 网络字节顺序,需要通过函数 htons 转换
主机结构
struct hostent
{ char *h_name ; //主机的正式名称
char * *h_aliases ; //别名列表
int h_addrtype ; //主机地址类型:AF_XXX
lnt H_length; //主机地址长度:4 字节(32 位)
char * *h_addr_list;//主机 IP 地址列表
}
函数库
1. int socket(int domain,int type,int protocol);
函数 socket 创建一个套接字描述符,如果失败返回 -1.domain为地址类型AF_XXX,type为套接字类型,SOCK_STREAM(TCP),SOCK_DGRAM (UDP),SOCK_RAW(IP、ICMP);protocol 指定协议 0为默认模式 。
2. int bind(int sockfd,struct sockaddr *hostaddr,int addrlen);
函数bind将本地地址与套接字绑定在一起,成功返回0,失败为-1,并设置全局变量errno为错误类型
EADDRINUSER。
3. int connect( int sockfd,struct sockaddr *servaddr, int addrlen);
函数connect与服务器建立一个连接,成功返回 0,失败返回- 1。servaddr 为远程服务器的套接字地址,包括服务器的 IP 地址和端口号;addrlen 为地址的长度。
4. int accept(int sockfd,struct sockaddr *addr,int *addrlen)
函数accept从listen的完成连接队列中接收一个连接,如果连接队列为空,则该进程睡眠。
5. int listen(int sockfd,int backlog);
函数listen 将一个套接字转换为倾听套接字,执行成功返回0,失败为-1。backlog设置请求队列的最大长度。
6. int write( int fd,char *buf,int len);
7. int read ( int fd,char *buf,int len);
函数read和write从套接字读和写数据,成功返回数据量大小,否则返回 -1.buf 指定数据缓冲区,len 指定接收或发送的数据量大小。
8. int close(int sockfd);
函数close关闭一个套接字描述符,成功返回0,失败为-1。
9. struct hostent * gethostbyname( const char *hostname);
函数 gethostbyname 查询指定的域名地址对应的 IP 地址,返回一个 hostent结构的指针,如果不成功返回 NULL。
附带函数
htons()
ntohs()
htonl()
ntohl()
在写整型数据前,先转换一下:
i= htonl(i);
write_data(s, &i, sizeof(i));
struct sockaddr_in
{
short int sin_family; //地址类型 AF_XXX(AF_UNIX,AF_INET和AF_NS)
unsigned short int sin_port; //16位端口号
struct in_addr sin_addr; //32位IP地址
char sin_zero[8]; //保留
} //端口号以及 Internet 地址使用的是 网络字节顺序,需要通过函数 htons 转换
主机结构
struct hostent
{ char *h_name ; //主机的正式名称
char * *h_aliases ; //别名列表
int h_addrtype ; //主机地址类型:AF_XXX
lnt H_length; //主机地址长度:4 字节(32 位)
char * *h_addr_list;//主机 IP 地址列表
}
函数库
1. int socket(int domain,int type,int protocol);
函数 socket 创建一个套接字描述符,如果失败返回 -1.domain为地址类型AF_XXX,type为套接字类型,SOCK_STREAM(TCP),SOCK_DGRAM (UDP),SOCK_RAW(IP、ICMP);protocol 指定协议 0为默认模式 。
2. int bind(int sockfd,struct sockaddr *hostaddr,int addrlen);
函数bind将本地地址与套接字绑定在一起,成功返回0,失败为-1,并设置全局变量errno为错误类型
EADDRINUSER。
3. int connect( int sockfd,struct sockaddr *servaddr, int addrlen);
函数connect与服务器建立一个连接,成功返回 0,失败返回- 1。servaddr 为远程服务器的套接字地址,包括服务器的 IP 地址和端口号;addrlen 为地址的长度。
4. int accept(int sockfd,struct sockaddr *addr,int *addrlen)
函数accept从listen的完成连接队列中接收一个连接,如果连接队列为空,则该进程睡眠。
5. int listen(int sockfd,int backlog);
函数listen 将一个套接字转换为倾听套接字,执行成功返回0,失败为-1。backlog设置请求队列的最大长度。
6. int write( int fd,char *buf,int len);
7. int read ( int fd,char *buf,int len);
函数read和write从套接字读和写数据,成功返回数据量大小,否则返回 -1.buf 指定数据缓冲区,len 指定接收或发送的数据量大小。
8. int close(int sockfd);
函数close关闭一个套接字描述符,成功返回0,失败为-1。
9. struct hostent * gethostbyname( const char *hostname);
函数 gethostbyname 查询指定的域名地址对应的 IP 地址,返回一个 hostent结构的指针,如果不成功返回 NULL。
附带函数
htons()
ntohs()
htonl()
ntohl()
在写整型数据前,先转换一下:
i= htonl(i);
write_data(s, &i, sizeof(i));
在读整型数据后,再转变回来:
read_data(s, &i, sizeof(i));
i= ntohl(i);
示例
#include /* obligatory includes */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define PORT 3490
int main( int argc,char *argv[] )
{ int sockfd,nbytes; //套接字描述符、读入缓冲区的字节数
char buf[1024]; //缓冲区
struct hostent *he; //主机信息类型
struct sockaddr_in srvaddr;//Internet套接字结构
if ( (1) argc!=2 )
{ perror( "调用参数为零,请输入服务器的主机名!/n" ); exit(1);}
if ( (2) (he=gethostbyname(argv[1]))==NULL) //如果通过主机名没有获得对应的主机 信息就提示用户
{ perror("无法通过主机名获得主机信息!/n" ); exit(1);}
if ( (3)(sockfd=socket(AF_INET,SOCK_STREAM.0))==-1 ) //在无法创建套接字时,
提示用户
{ perror("无法创建套按字!/n" ); exit(1);}
bzero( &srvaddr,sizeof(srvaddr));//置空 srvaddr
srvaddr.sin_family = AF_INET;
srvaddr.sin_port=(4)htons(PORT) ;
srvaddr.sin_addr=(5)*((struct in_addr *)he->h_addr) ;
//设置套接字结构的各项信息,其中的地址来自于域名查询后的 hp 变量
if(connect( sockfd, (6)(struct sockaddr *)&srvaddr,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) ;
//打印数据并关闭套接字
read_data(s, &i, sizeof(i));
i= ntohl(i);
示例
#include /* obligatory includes */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define PORT 3490
int main( int argc,char *argv[] )
{ int sockfd,nbytes; //套接字描述符、读入缓冲区的字节数
char buf[1024]; //缓冲区
struct hostent *he; //主机信息类型
struct sockaddr_in srvaddr;//Internet套接字结构
if ( (1) argc!=2 )
{ perror( "调用参数为零,请输入服务器的主机名!/n" ); exit(1);}
if ( (2) (he=gethostbyname(argv[1]))==NULL) //如果通过主机名没有获得对应的主机 信息就提示用户
{ perror("无法通过主机名获得主机信息!/n" ); exit(1);}
if ( (3)(sockfd=socket(AF_INET,SOCK_STREAM.0))==-1 ) //在无法创建套接字时,
提示用户
{ perror("无法创建套按字!/n" ); exit(1);}
bzero( &srvaddr,sizeof(srvaddr));//置空 srvaddr
srvaddr.sin_family = AF_INET;
srvaddr.sin_port=(4)htons(PORT) ;
srvaddr.sin_addr=(5)*((struct in_addr *)he->h_addr) ;
//设置套接字结构的各项信息,其中的地址来自于域名查询后的 hp 变量
if(connect( sockfd, (6)(struct sockaddr *)&srvaddr,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) ;
//打印数据并关闭套接字