深入理解计算机系统
套接字 网络上IP和端口采用大端
// IP地址结构
struct in_addr {
unsigned int s_addr ; //1.2.3.4 -> 0x04030201
};
//DNS主机条目结构
struct hostent {
char * h_name ; // "localhost"
char ** h_aliases ; // Null-terminated array of domain names
int h_addrtype ; // AF_INET
int h_length ; // 32
char ** h_addr_list ; // Null-terminated array of in_addr structs
};
//常规socket地址结构
struct sockaddr {
unsigned short sa_family ; // Protocol family
char sa_data [ 14 ]; // Address data.
};
//网络socket地址结构
struct sockaddr_in {
unsigned short sin_family ; //AF_INET
unsigned short sin_port ; // 端口
struct in_addr sin_addr ; //IP
unsigned char sin_zero [ 8 ];
};
int socket (int domain, int type, int protocol); int connect (int sockfd, const struct sockaddr *addr, socklen_t addrlen); int setsockopt (int sockfd, int level, int optname, const void *optval, socklen_t optlen); int bind (int sockfd, const struct sockaddr *addr, socklen_t addrlen); int listen (int sockfd, int backlog);
// 客户端
int open_clientfd ( char * hostname , int port ){
int clientfd ;
struct hostent * hp ;
struct sockaddr_in serveraddr ;
if (( clientfd = socket ( AF_INET , SOCK_STREAM , 0 )) < 0 )
return - 1 ;
if (( hp = gethostbyname ( hostname )) == NULL )
return - 2 ;
bzero (( char * ) & serveraddr , sizeof ( serveraddr ));
serveraddr . sin_family = AF_INET ;
bcopy (( char * ) hp -> h_addr_list [ 0 ],
( char * ) & serveraddr . sin_addr . s_addr , hp -> h_length );
serveraddr . sin_port = htons ( port ); // (80=0x0050) => 0x5000
// 阻塞
if ( connect ( clientfd , ( struct sockaddr * ) & serveraddr , sizeof ( serveraddr )) < 0 )
return - 1 ;
return clientfd ;
}
//服务端
int open_listenfd ( int port ){
int listenfd , optval = 1 ;
struct sockaddr_in serveraddr ;
if (( listenfd = socket ( AF_INET , SOCK_STREAM , 0 )) < 0 )
return - 1 ;
if ( setsockopt ( listenfd , SOL_SOCKET , SO_REUSEADDR ,( const void * ) & optval , sizeof ( int )) < 0 )
return - 1 ;
bzero (( char * ) & serveraddr , sizeof ( serveraddr ));
serveraddr . sin_family = AF_INET ;
serveraddr . sin_addr . s_addr = htonl ( INADDR_ANY ); // 0.0.0.0 -> 0x00000000
serveraddr . sin_port = htons (( unsigned short ) port ); // 80 -> 0x5000
if ( bind ( listenfd , ( struct sockaddr * ) & serveraddr , sizeof ( serveraddr )) < 0 )
return - 1 ;
if ( listen ( listenfd , 1024 ) < 0 )
return - 1 ;
return listenfd ;
}