数据结构
sockaddr
struct sockaddr {
sa_family_t sin_family;//地址族
char sa_data[14]; //14字节,包含套接字中的目标地址和端口信息
};
缺点:a_data把目标地址和端口信息混在一起了
sin_family在socket编程中只能是AF_INET(表示TCP/IP协议)
sockaddr_in
如果要记录网络通信的地址,一般用sockaddr_in,然后转型成sockaddr,因为sin_port+sin_addr+sin_zero[8]大小刚好与sa_data[14]相等,所以两个数据结构占用内存相等
in_addr
sockaddr_in中记录IP地址的部分
linux下
typedef uint32_t in_addr_t;
struct in_addr
{
in_addr_t s_addr;
};
windows下
用了union,有三种表示方法
typedef struct in_addr
{
union{
struct { unsigned char s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { unsigned short s_w1,s_w2; } S_un_w;
unsigned long S_addr;
}S_un;
}in_addr;
WSADATA
用来存储被WSAStartup函数调用后返回的 Windows Sockets数据。
hostent
host entry的缩写,用以记录主机的信息
struct hostent
{
char *h_name; //正式主机名
char **h_aliases; //主机别名
int h_addrtype; //主机IP地址类型:IPV4-AF_INET
int h_length; //主机IP地址字节长度,对于IPv4是四字节,即32位
char **h_addr_list; //主机的IP地址列表
};
函数
WSAStartup
WSAStartup(WSWENS, &wsadata)
当一个应用程序调用WSAStartup函数时,操作系统根据请求的Socket版本来搜索相应的Socket库,然后绑定找到的Socket库到该应用程序中。以后应用程序就可以调用所请求的Socket库中的其它Socket函数了。
gethostbyname
hostent* hptr = gethostbyname("www.baidu.com");
解析一个域名,返回一个hostent
socket
socket(int domain, int type, int protocol);
domain
type
protocol
用于制定某个协议的特定类型,通常某协议中只有一种特定类型,这样protocol参数仅能设置为0。
示例
SOCKET s = socket(PF_INET,SOCK_STREAM,0);
connect
int connect(SOCKET s, const struct sockaddr * name, int namelen);
参数
s:标识一个未连接socket
name:指向要连接套接字的sockaddr结构体的指针
namelen:sockaddr结构体的字节长度
返回值
成功则返回0, 失败返回-1, 错误原因存于errno 中
示例
SOCKET s = socket(PF_INET,SOCK_STREAM,0);
sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(25);
hostent* hptr = gethostbyname("smtp.qq.com");
memcpy(&sin.sin_addr.S_un.S_addr, hptr->h_addr_list[0], hptr->h_length);
if(connect(s, (sockaddr*)&sin, sizeof(sin))){
cout << "connect failed!" << endl;
exit(0);
}
else{
cout << "connect success!" << endl;
}
send
int send( SOCKET s, const char FAR *buf, int len, int flags );
参数
(1)第一个参数指定发送端套接字描述符;
(2)第二个参数指明一个存放应用程序要发送数据的缓冲区;
(3)第三个参数指明实际要发送的数据的字节数;
(4)第四个参数一般置0。
recv
int recv( SOCKET s, char *buf, int len, int flags);
参数
(1)第一个参数指定接收端套接字描述符;
(2)第二个参数指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据;
(3)第三个参数指明buf的长度;
(4)第四个参数一般置0。
closesocket
int closesocket( SOCKET s);
返回值
如无错误发生,则closesocket()返回0。否则的话,返回SOCKET_ERROR错误,应用程序可通过WSAGetLastError()获取相应错误代码。