Socket程序设计入门(一)
Socket编程基本API分析
1.WORD类型分析
WORD类型是一个16位的无符号整型,定义如下
typedef unsigned short WORD;
提供两个字节的存储,在Socket中这个两个字节可以分别用来表示主版本号和副版本号
2.MAKEWORD宏
WORD MAKEWORD(BYTE bLow, BYTE bHigh);
将两个byte型合并成一个WORD型,一个在高8位,一个在低8位
返回一个WORD变量
3.WSADATA
在WSAStarup()函数中作为一个返回值,存储这个函数加载的Socket的初始化信息
把WSADATA的指针类型LPWSADA作为返回值传入WSAStarup(),
typedef struct WSAData{
…
…
}WSADATA, FAR *LPWSADATA
4.WSAStarup()
函数声明:
int WSAStarup(WORD wVersionRequested, LPWSADATA lpWSAData);
返回:返回int型,返回0则初始化成功,SOCKET_ERROR表示失败
初始化socket的程序段如下:
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(1.1);
err = WSAStarup(wVersionRequested, &wsaData);
if(err != 0){
return 0;
}
5.SOCKET类型
SOCKET是socket套接字类型,WINSOCK2.H中定义如下:
typedef unsigned int u_int;
typedef u_int SOCKET
套接字实际上是一个无符号整型,被Socket环境管理和使用,套接字将被创建,设置,用来发送和接受数据,最后会被关闭。
6.socket()函数
SOCKET socket(int af, int type, int protocol);
参数:第一个参数是地址组 TCP/IP的地址组为AF_INET
第二个参数是Socket类型,SOCK_STREAM是流式套接字,SOCK_DGRAM是数据报套接字
第三个参数指定为0
返回值:成功 返回一个SOCKET类型的套接字描述符
失败 返回一个INVALID_SOCKET值
7.SOCKADDR和sockaddr
struct sockaddr{
u_short sa_family;
char sa_data[14];
}
typedef struct sockaddr SOCKADDR;
第一个字段sa_family指定地址家族
第二个字段申请一块内存区域
对不同的协议家族用不同的结构替换sockaddr,TCP/IP中用sockaddr_in替换sockaddr
注:sockaddr按网络字节顺序表示
8.in_addr类型
struct in_addr{
unio{
struct{u_char s_b1, s_b2, s_b3, s_b4;} S_un_b;
struct{u_short s_w1, s_w2;} S_un_w;
u_long S_addr;
}S_un;
};
typedef struct in_addr IN_ADDR;
in_addr结构实际上是一个联合,利用这个结构将一个char *类型表示的点分十进制的IP地址转换为u_long类型,并将结果赋给成员S_addr
9.unsigned long inet_addr(const char FAR* cp);
参数:传入一个const char *类型表示的点分十进制格式的IP地址
返回:一个适合分配给S_addr的u_long类型的整型
10.SOCKADDR_IN和sockaddr_in
struct sockaddr_in{
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
typedef struct sockaddr_in SOCKADDR_IN;
注:全大写和全小写的关系一般为大写类型为小写的typedef形式
sin_family 地址族 对于TCP/IP地址为AF_INET
sin_port 指定要分配给套接字的端口
sin_zero[8] 填充数,使sockaddr_in结构和sockaddr结构的长度一样
sin_addr 是一个in_addr类型
创建套接字及地址结构的程序段
SOCKET sockSrv = socket(AF_INET, SOCK_DGRAM, 0);
SOCKADDR_IN addrSrv;
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htos(6000);
addrSrv.sin_addr_S_un.S_addr = htol(INADDR_ANY);
11.bind()函数
int bind(SOCKET s, const struct sockaddr FAR*name, int namelen);
参数:
要绑定的套接字,这个套接字要绑定的地址结构类型为SOCKADDR *,第三个参数是SOCKADDR地址结构的长度
注:
bind()函数参数中要求的地址结构类型为SOCKADDR *,而TCP/IP协议族中的地址结构为SOCKADDR_IN,所以在此API中要将之前创建的SOCKADDR_IN类型的地址结构强制转换为SOCKADDR*
绑定套接字s到一个地址结构的程序语句如下:
bind(sockSrv, (SOCKADDRA*)&addrSrv, sizeof(SOCKADDR))
注:
Socket编程有关的API中,当一个参数是SOCKADDR的地址结构类型时,随后的参数一般是这个结构类型的长度(单位是字节)