|
套接字结构
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) ; //打印数据并关闭套接字
|