在windows下进行TCP的Socket编程主要有以下步骤:
1.初始化WSA(Winsock):
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 2, 0 );
if(WSAStartup( wVersionRequested, &wsaData ) != 0)
{
return false;
}
WSADATA wsaData;
wVersionRequested = MAKEWORD( 2, 0 );
if(WSAStartup( wVersionRequested, &wsaData ) != 0)
{
return false;
}
2.建立一个socket
SOCKET socket(
int af,
int type,
int protocol
);
int af,
int type,
int protocol
);
SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);
socket 的地址格式:AF_UNIX 就象 UNIX 路径名一样识别 sockets。这种形式对于在同一台机器上的 IPC 很有用。而
AF_INET 使用象
192.9.200.10 这样被点号隔开的四个
十进制数字的地址格式。
socket 的类型:SOCK_STREAM表明数据象字符流一样通过 socket(TCP) 。而 SOCK_DGRAM(UDP) 则表明数据将是
数据报(datagrams)的形式。
protocol通常赋值为0
3.连接到服务器
SOCKADDR_IN addrSrv;
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(5099);
addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(5099);
addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
sockaddr_in(在netinet/in.h中定义):
struct sockaddr_in {
short int sin_family; /* Address family指代协议族,在socket编程中 只能是AF_INET */
unsigned short int sin_port; /* Port number 存储端口号(使用网络字节顺序)*/
struct in_addr sin_addr; /* Internet address 存储IP地址,使用in_addr这个数据结构 */
unsigned char sin_zero[8]; /* Same size as struct sockaddr 为了让sockaddr与sockaddr_in两个 数据结构保持大小相同而保留的空字节*/
};
struct sockaddr_in {
short int sin_family; /* Address family指代协议族,在socket编程中 只能是AF_INET */
unsigned short int sin_port; /* Port number 存储端口号(使用网络字节顺序)*/
struct in_addr sin_addr; /* Internet address 存储IP地址,使用in_addr这个数据结构 */
unsigned char sin_zero[8]; /* Same size as struct sockaddr 为了让sockaddr与sockaddr_in两个 数据结构保持大小相同而保留的空字节*/
};
//在windows下:
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;
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;
if(connect(sockClient, (struct sockaddr*)&addrSrv, sizeof(addrSrv)) == INVALID_SOCKET)
connect(
SOCKET s,
const struct sockaddr FAR * name,
int namelen
);
第一个参数是客户端的套接字(表明即将发起连接请求),第二个参数是服务端的套接字所在的“地方”(“地方”是我自定义的专有名词),第三个参数是该“地方”的大小。 如果请求连接成功,则返回0,否则返回错误码。
int send( SOCKET s, const char FAR *buf, int len, int flags );
第一个参数指定发送端套接字描述符;
第二个参数指明一个存放应用程序要发送数据的缓冲区;
第三个参数指明实际要发送的数据的字节数;
第四个参数一般置0。
第二个参数指明一个存放应用程序要发送数据的缓冲区;
第三个参数指明实际要发送的数据的字节数;
第四个参数一般置0。
int recv( SOCKET s, char FAR *buf, int len, int flags );
第一个参数指定接收端套接字描述符;
第二个参数指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据;
第三个参数指明buf的长度;
第四个参数一般置0。
第二个参数指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据;
第三个参数指明buf的长度;
第四个参数一般置0。