欢迎使用CSDN-markdown编辑器

WinSock API 函数介绍

socket通信的整个过程:
socket通信的整个过程:
1.WSAStartup()

使用Socket之前必须调用WSAStartup函数,此函数在应用程序中用来初始化Windows Sockets DLL,只有此函数调用成功后,应用程序才可以调用Windows SocketsDLL中的其他API函数,否则后面的任何函数都将调用失败。

为了支持日后各种不同功能winsock实现和应用,在WSAStartup函数中做了协商。WSAStartup函数的调用方和Windows Sockets DLL互相通知对方它们可以支持的最高版本。并且互相确认对方的最高版本是可接受的。

在WSAStartup函数的入口,Windows Sockets DLL检查了应用程序所需的版本.如果版本高于DLL支持的最低版本,则调用成功并且DLL在wHighVersion中返回它所支持的最高版本,在wVersion中返回它的高版本和wVersionRequested中的较小者,然后Windows Sockets DLL就会假设应用程序将使用wVersion。如果WSDATA结构中的wVersion域对调用方来说不可接收, 它就应调用WSACleanup函数并且要么去另一个Windows Sockets DLL中搜索,要么初始化失败。

函数原型

int WSAStartup(  
       __in      WORD wVersionRequested,  
       __out      LPWSADATA lpWSAData  
       );


 

wVersionRequested

调用程序使用windows socket的最高版本。 高字节指定小的版本号,低字节指定高的版本号。

lpWSAData

指向WSADATA数据结构体指针,接收Windows Socket的实现细节。

WSADATA结构体
typedef struct WSAData{
WORD wVersion;
WORD wHighVersion;
char szDescription[WSADESCRIPTION_LEN +1];
char szSystemStatus[WSASYS_STATUS_LEN +1];
unsigned short iMaxSockets;
unsigned short iMaxUdpDg;
char FAR* ipVendorInfo;
}WSADATA,*LPWSADATA;

返回值

如果成功,WSAStartup函数返回0。否则,返回下面列表显示的错误码之一。

WSAStartup函数直接在返回值中返回扩展的错误码,不再需要调用WSAGetLastError函数。

错误码

解释

WSASYSNOTREADY

网络通信中下层的网络子系统没准备好

WSAVERNOTSUPPORTED

Socket实现提供版本和socket需要的版本不符

WSAEINPROGRESS

一个阻塞的Socket操作正在进行

WSAEPROCLIM

Socket的实现超过Socket支持的任务数限制

WSAEFAULT

lpWSAData参数不是一个合法的指针

说明

一旦一个应用或者DLL成功调用WSAStartup函数,应用程序才可以处理其他的winsock 中的其他函数。当应用或者DLL调用Winsock DLL服务完成,必须调用WSACleanup函数,此函数让Winsock DLL释放应用用到的Winsock资源。

应用可以调用WSAStartup不止一次,如果它需要获得WSADATA结构体信息不止一次。在每次调用时,应用可以指定任何winsock DLL支持的版本数。

WSAStartup函数通常导致具体协议帮助DLL一直加载,因此,WSAStartup函数不能被一个DLL应用的DLLMain函数调用。这样可能导致死锁的发生。

应用必须调用WSAClearup函数在每次成功调用WSAStartup函数。这就意味着,例如应用调用WSAStartup函数三次,它也需要调用WSAClearup函数三次。前两次调用WSAClearup函数除了减少内部计数器什么都不做,最后一个次调用WSAClearup函数则释放任务使用的需要的资源。

2 socket()函数
完成Windows Socket DLL初始化以后,就是创建套接字。Socket()函数完成此任务。建立的是流式套接字还是数据报套接字也是在调用这个函数中指定的。
函数声明如下:
SOCKET socket(
int af,int type,int protocol
);
其中:
af:协议的地址家族,创建TCP或者UDP套接字时,指定为AF_INET.
type:非常重要,指定协议的套接字类型。流式套接字为SOCK_STREAM,数据报套接字为SOCK_DGRAM.
protocol:协议。指定的地址家族和套接字类型有多个数量时,使用该字段来限定一个特殊的传输。对于流式套接字取IPPROTO_TCP获0;对于数据报套接字取IPPROTO_UDP或0.
3 bind()函数
此函数将套接字与已知地址进行绑定,该函数声明如下:
int bind(
SOCKET s,
const struct sockaddr FAR *name,
int namelen
);
其中:
s:要绑定的套接字。
name:指向socketaddr结构的指针,代表地址。
namelen:sockaddr 结构的长度。
这里需要重点说明的是sockaddr结构体以及另一个和它密切相关的重要结构体sockaddr_in.sockaddr结构依据使用协议的不同而不同,被内核用于存储地址,大小为16字节,声明如下:
struct sockaddr{
u_short sa_family;
char sa_data[14];
};
TCP/IP编程中,使用sockaddr_in 结构代替sockaddr结构。sockaddr_in结构用来指定IP地址和端口号。

struct sockaddr_in{
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
其中:
sin_family:地址家族,必须为AF_INET,代表使用IP地址家族。
sin_port:端口号,通常选择1024~49151范围内的数字。
sin_addr:in_addr类型的IP地址。
sin_zero:没有实际意义,只是填充结构体使之与sock_addr类型大小相同。
当调用bind()函数进行套接字绑定时,将sockaddr_in结构类型强制转换为sockaddr类型,以作为第二个参数。

返回值:
bind()函数调用成功,则返回0;否则,返回SOCKET_ERROR.

4 listen()函数
listen()函数将套接字设为监听模式,以等待客户端的连接请求。其声明如下:
int listen(
SOCKET s,
int backlog
);
其中;
s:套接字。
backlog:指定等待连接的最大队列长度。
该函数调用成功,返回0;否则,返回SOCKET_ERROR.
需要说明的是,backlog参数比较重要,如其值被设为4,则说明最多同时只能有4个客户端可供连接,如果此时有5个客户端向服务器发出连接请求,那么第五个连接将无法成功,造成WSAECONNREFUSED错误。
5 accept()函数
此函数用于接受一个客户端连接请求的功能,声明如下:
SOCKET accept(
SOCLET s,
struct sockaddr FAR *addr,
int FAR * addrlen
);

其中;
s:监听套接字。
addr:该参数返回请求连接的客户端的地址。
addrlen:该参数返回sockaddr结构的长度。
该函数若调用成功,则返回一个新的套接字句柄,服务器使用此句柄与客户端进行通信,监听套接字仍然用于接受客户端的连接,addr结构返回请求连接的客户端的地址信息;若调用失败,则accept()函数返回INVALID_SOCKET错误。
6 connect()函数
此函数用于流式TCP套接字编程模式中客户端对于服务器的连接。声明如下:
int connetc(
SOCKET s,
const struct sockaddr FAR* name,
int namelen
);
其中;
s:套接字。
name: 要连接的服务器地址。
namelen:sockaddr结构的长度。
该函数若调用成功,则返回0;否则,返回SOCKET_ERROR错误。

7 recv()函数
此函数用于流式TCP套接字接收数据。声明如下:
int recv(
SOCKET s,
char FAR *buf,
int len,
int flags
);
其中:
s:套接字。
buf:接收数据缓冲区。
len:接收数据缓冲区长度。
flags:该参数影响函数的具体行为。可取0、MSG_PEEK、和MSG_OOB.其中,0表示无特殊行为;MSG_PEEK会使有用的数据被复制到接收缓冲区中,但没有从接收缓冲区中删除;MSG_OOB表示处理带外数据。
该函数成功返回时,返回值为接收的字节数;调用失败时,返回SOCKET_ERROR.
8 recvfrom()函数
此函数用于数据报UDP套接字接收数据,并且返回发送数据的主机地址。声明如下:

int recvfrom(
SOCKET s,
char FAR *buf,
int len,
int flags,
struct sockaddr FAR *from,
int FAR *fromlen
);
  
  其中:
s:套接字。
buf:接收数据缓冲区。
len:接收数据缓冲区长度。
flags:该参数影响函数的具体行为。可取0、MSG_PEEK、和MSG_OOB.其中,0表示无特殊行为;MSG_PEEK会使有用的数据被复制到接收缓冲区中,但没有从接收缓冲区中删除;MSG_OOB表示处理带外数据。
from:该参数返回发送数据主机的地址。
fromlen:地址长度。
该函数调用成功后,返回接收数据的字节数;反之,调用失败,则返回SOCKET_ERROR错误。
9 send()函数
此函数用于流式套接字(基于TCP)发送数据。声明如下:
int send(
SOCKET s,
char FAR *buf,
int len,
int flags
);
其中:
s:套接字。
buf:发送数据缓冲区。
len:发送数据缓冲区长度。
flags:该参数影响函数的具体行为。可取0、MSG_PEEK、和MSG_OOB.其中,0表示无特殊行为;MSG_PEEK会使有用的数据被复制到接收缓冲区中,但没有从接收缓冲区中删除;MSG_OOB表示处理带外数据。
该函数成功返回时,返回值为接收的字节数;调用失败时,返回SOCKET_ERROR.

10 sendto()函数
此函数用于数据报套接字(基于UDP)发送数据。声明如下:
int sendto(
SOCKET s,
const char FAR *buf,
int len,
int flags,
const struct sockaddr FAR *to,
int tolen
);
其中:
s:套接字。
buf:发送数据缓冲区。
len:发送数据缓冲区长度。
flags:该参数影响函数的具体行为。可取0、MSG_PEEK、和MSG_OOB.其中,0表示无特殊行为;MSG_PEEK会使有用的数据被复制到接收缓冲区中,但没有从接收缓冲区中删除;MSG_OOB表示处理带外数据。
to:接收数据端的地址。
tolen:地址长度。
该函数调用成功后,返回发送数据的字节数;反之,调用失败,则返回SOCKET_ERROR错误。

11.closesocket()函数
此函数用于关闭套接字、释放所占资源。声明如下:
int closesocket(
SOCKET s
);
该函数调用成功后,返回0;反之,调用失败,则返回SOCKET_ERROR错误。
当调用完此函数后,如果继续使用套接字执行操作,则会返回WSAENOT-SOCK错误。

12 shutdown()函数
此函数用于通知对方不再发送数据、不再接收数据或者不发送也不接收。声明如下:
int shutdown(
SOCKET s,
int how
);
其中:
s:套接字。
how:此参数为SD_RECEIVE时,表示不允许再调用接收数据函数;取值为SD_SEND时,表示不允许再调用发送数据函数;如取值为SD_BOTH,则表示既不允许发送也不允许接收。
13 WSAClean()函数
此函数用于终止Winsock 2 DLL (Ws2_32.dll) 的使用.此函数用于完成了Windows Sockets的使用后,将应用程序或DLL从Windows Sockets的实现中注销,并且该释放为应用程序或DLL分配的任何资源,任何打开的并已建立连接的SOCK_STREAM类型套接口在调用WSACleanup()时会重置;而已经由closesocket()关闭却仍有要发送的悬而未决数据的套接口则不会受影响——该数据仍要发送。
此函数声明:
int WSAClean(void);
对应于一个任务进行的每一次WSAStartup()调用,必须有一个WSAClean()调用。此函数操作成功,返回0;调用失败,则返回SOCKET_ERROR.

函数调用顺序:这里写图片描述

这里写图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值