使用socket函数创建一个套接字对象:
SOCKET socket(
int af, //指定套接字使用的地址格式,winsock只支持AF_INET
int type, //指定套接字类型 SOCK_STREAM:流套接字(TCP) SOCK_DGRAM:数据报套接字(UDP)
int protocol //配合type参数使用,指定套接字类型
);
函数执行失败返回INVALID_SOCKET。
也可以使用Winsock2的新函数WSASocket来创建套接字,与socket相比,提供了更多参数。
当不使用socket创建的套接字时,应调用closesocket函数将其关闭。没有错误返回0,否则返回SOCKET_ERROR。
int closesocket(SOCKET s);
套接字被创建后存在于指定的地址家族里,但它是未命名的。bind函数通过安排一个本地名称到未命名的socket而建立此socket的本地关联。本地名称包含3各部分:主机地址、协议号、端口号。
int bind(
SOCKET s, //套接字句柄
const struct sockaddr* name, //要关联的本地地址
int namelen //地址的长度
);
举例:TCPServer程序使用一下代码绑定套接字s到本地地址。
//填充sockaddr_in结构
sockaddr_in sin;
sin.sin_family=AF_INET; //指定地址家族,与af参数含义相同,智能用AF_INET
sin.sin_port=htons(4567); //必须为网络字节顺序,因为与Intel字节顺序相反,必须用htons函数转换
sin.sin_addr.S_un.S_addr=INADDR_ANY;
//若应用程序不关心所使用地址,可指定Internet地址为INADDR_ANY,系统自动使用当前主机配置的所有IP地址
//绑定这个套接字到一个本地地址
if(::bind(sListen,(LPSOCKADDR)&sin,sizeof(sin))==SOCKET_SRROR){
printf("Failed bind()\n");
return 0;
}
listen函数设置套接字进入监听状态。
int listen(
SOCKET s, //套接字句柄
int backlog //监听队列中允许保持的尚未处理的最大连接数量
);
listen仅用再支持连接的套接字上,如SOCK_STREAM类型的他套接字,函数执行成功后,套接字s进入被动模式,到来的连接会被通知要排队等候接受处理。
再同一时间处理多个连接请求的服务器通常使用listen函数,若一个连接请求到达,队列已满,客户端将受到WSAECONNREFUSED错误。
accept函数用于接受到来的连接。
SOCKET accept(
SOCKET s, //套接字句柄
struct sockaddr* addr, //一个指向sockaddr_in结构的指针,用于取得对方的地址信息
int* addrlen //一个指向地址长度的指针
);
对于流套接字来说,一般使用send和recv函数来收发数据。
int send(
SOCKET s, //套接字句柄
const char FAR* buf, //要发送数据的缓冲区地址
int len, //缓冲区长度
int flags //指定了调用格式,通常设置为0
);
int recv(SOCKET s,char FAR *buf,int len,int flags);
#include"../common/InitSock.h"
#include
ClnitSock initSock;
int main(){
//创建套接字
SOCKET sListen=::socket(AF_INET,SOCK_DGRAM,IPPROTO_TCP);
if(sListen==INVALID_SOCKET){
printf("Failed socket() \n");
return 0;
}
//填充sockaddr_in结构,绑定套接字到本地地址
sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(4567);
sin.sin_addr.S_un.S_addr=INADDR_ANY;
return 0;
}