SOCKET基础学习笔记

 PS:为了区分SOCKET函数版本,Winsock2版本前加WSA前缀,例如:socket WSASocket;对采用Winsock 1的应用而言,必须有Wi n s o c k . h包容文件,而对使用Winsock 2的应用而言,则需要Winsock 2.h包容文件。
int WSAGetLastError(void);发生错误之后调用这个函数,就会返回所发生的特定错误的完整代码。
一旦为某种特定协议创建了套接字,就必须将套接字绑定到一个已知地址。
int bind(
SOCKET s; //希望在上面等待客户机联机的套接字
const struct sockaddr FAR* name; //地址缓冲区
int namelen;
);
SOCKET s;
struct sockaddr_in tcpaddr;
int port=5150;
s=socket(AF_INET,SOCK_STRAM,IPPROTO_TCP);
tcpaddr.sin_family=AF_INET;
tcpaddr.sin_port=htons(port);
tcpaddr.sin_addr.s_addr=htonl(INADDR_ADY);
bind(s,(SOCKADDR*)&tcpaddr,sizeof(tcpaddr));
b i n d函数的作用只是将一个套接字和一个
指定的地址关联在一起。指示一个套接字等候进入连接的A P I函数则是l i s t e n
int listen(
SOCKET s,
int backlog //等待连接的最大个数
);
当我们都做好准备时,就可以用accept函数来接受连接
SOCKET accepy(
SOCKET s,
struct sockaddr FAR* addr,//发出连接请求的套接字信息
int FAR* addrlen //第二个参数的长度
);
a c c e p t会返回一个新的套接字描述符,它对应于已经接受的那个客户机连接。对于该客户机后续的所有操作,都应使用这个新套接字。至于原来那个监听套接字,它仍然用于接受其他客户机连接,而且仍处于监听模式。
SOCKET WSAAccept(
SOCKET s,
struct sockaddr FAR* addr,
LPINT addrlen,
LPCONDITIONPROC lpfnCondition, //回调函数定义如下
DWORD dwCallbackData //?????
);
int CALLBACK ConditionFunc(
LPWSABUF lpCallerId, //连接实体的地址
LPWSABUF lpCallerData, //连接实体附带的请求数据(一般不支持)
LPQOS lpSQOS, //独立连接时需要的带宽
LPQOS lpGQOS, //套接字组连接需要的带宽(不支持)
LPWSABUF lpCalleeId, //客户机连接的本地地址
LPWSABUF lpCalleeData, //可以作为连接请求的一部分返回给客户机(一般不支持)
GROUP FAR* g,//???????
DWORD dwCallbackData //?????????
);
typedef struct _WSABUF{
u_long len;
char FAR* buf;
}WSABUF,FAR* LPWSABUF;
connect函数和WSAConnect函数
int connect(
SOCKET s,
const struct sockaddr FAR* name,
int namelen
);
int WSAConnect(
SOCKET s,
const struct sockaddr FAR* name,
int namelen,
LPWSABUF lpCallerData, //发送给服务器的附加数据
LPWSABUF lpCalleeData,//服务器传回的附加数据(不支持)
LPQOS lpSQOS, //套接字需要的网络质量
LPQOS lpGQOS
);
数据收发没有Unicode版本,所以经常用到WideCharToMultiByte把UNICODE转换为ASCII版本
int send(
SOCKET s,
const char FAR* buf,
int len,
int flags
);
l a g s可为0、M S G _ D O N T R O U T E或M S G _ O O B。另外, f l a g s还可以是对那些标志进行按位“或运算”的一个结果。M S G _ D O N T R O U T E标志要求传送层不要将它发出的包路由出去。
M S G _ O O B标志预示数据应该被带外发送(紧急数据)
int WSASend(
SOCKET s,
LPWSABUF lpBuffers, //发送的一组结构多用于分散集合I/O
DWORD dwBufferCount, //传送的结构数
LPDWORD lpNumberOfBytesSent, //字节总发送数
DWORD dwFlags,
LPWSAOVERLAPPED lpOverlapped, //用于重叠I/O
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionROUTINE //用于重叠I/O
);
int recv(
SOCKET s,
char FAR* buf,
int len,
int flags
);
f l a g s参数可以是下面的值: 0、M S G _ P E E K或M S G _ O O BM S G _ P E E K会使有用的数据复制到所提供的接收端缓冲内,但是没有从系统缓冲中将它删除
int WSARecv(
SOCKET s,
LPWSABUF lpBuffers,
DWORD deBufferCount,
LPDWORD lpNumberOfBytesReceived,
LPDWORD lpFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionROUTINE
);
M S G _ PA RT I A L标志使用和出现的地方不同,其含义也不同。对面向消息的协议来说,这个标志是W S A R e c v调用返回后设置的(如果因为缓冲空间不够导致整条消息未能在这次调用中返回的话)。这时,后面的W S A R e c v调用就会设置这个标志M A S G _ PA RT I A L,直到整条消息返回,才把这个标志清除。如果这个标志当作一个输入参数投递,接收操作应该在一收到数据就结束,即使它收到的只是整条消息中的一部分。
int shutdown(
SOCKET s,
int how
); //用于从容关闭端口
h o w参数可以是下面的任何一个值: S D _ R E C E I V E、S D _ S E N D或S D _ B O T H。如果是
S D _ R E C E I V E,就表示不允许再调用接收函数。这对底部的协议层没有影响。另外,对T C P套接字来说,不管数据在等候接收,还是数据接连到达,都要重设连接。尽管如此, U D P套接字上,仍然接受并排列接入的数据。如果选择S E _ S E N D,表示不允许再调用发送函数。对T C P套接字来说,这样会在所有数据发出,并得到接收端确认之后,生成一个F I N包。最后,如果指定S D _ B O T H,则表示取消连接两端的收发操作。
无连接协议下
int recvfrom(
SOCKET s,
char FAR* buf,
int len,
int flags, //M S G _ O O B和M S G _ P E E K
struct sockaddr FAR* from,
int FAR* fromlen
);
int WSARecvFrom(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesReceivd,
LPDWORD lpFlags, //0、M S G _ O O B、M S G _ P E E K或M S G _ PA RT I A L
struct sockaddr FAR* lpFrom,
LPINT lpFromlen,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPELTION_ROUTINE lpCompletionROUTINE
);
int sendto(
SOCKET s,
const char FAR* buf,
int len,
int flags,
const struct sockaddr FAR* to, //服务器目标地址
int tolen
):
int WSASendTo(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
DWORD dwBufferCount,
LPDWROD lpNumberOfBytesSent,
DWORD dwFlags,
const struct sockaddr FAR* lpTo,
int iTolen,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_CONPLETION_ROUTINE lpCompletionROUTINE
);
其他函数
获得通信方的套接字地址信息,该信息是关于已建立连接的那个套接字的
int getpeername(                        
SOCKET s,
struct sockaddr FAR* name,
int FAR* namelen
);
指定套接字的本地接口的地址信息
getsockname(
SOCKET s,
struct sockaddr FAR* name,
int FAR* namelen
);
Tr a n s m i t F i l e
Tr a n s m i t F i l e是微软专有的Wi n s o c k扩展,它允许从一个文件中传输高性能数据。这是非常有效的,因为整个数据传输可在内核模式中进行。也就是说,如果你的应用从指定的文件中读取一堆数据,然后用s e n d或W S A S e n d时,涉及到“用户模式到内核模式传输”的发送调用就有若干个。有了Tr a n s m i t F i l e,整个读取和发送数据的进程就可在内核模式中进行。该函数的定义如下:
BOOL TransmitFile(
SOCKET hSocket,
HANDLE hFile,
DWORD nNumberOfBytesToWrite, //要发送的文件大小,0为全部
DWORD nNumberOfBytesPerSend, //以多大的数据块进行发送,0为默认
LPOVERLAPPED lpOverlapped,
LPTRASMIT_FILE_BUFFERS lpTrasmitBuffers, //文件传输之前和之后要发送的数据
DWORD dwFlags  //如下
);
typedef struct _TRANSMIT_FILE_BUFFERS{
PVOID Head; //文件发送之前要发送的数据
DWORD HeadLength;
PVOID Tail; //文件发送完成之后要发送的数据
DWORD TailLength;
}TRANSMIT_FILE_BUFFERS;
T F _ D I S C O N N E C T 数据发送完毕之后,开始执行套接字关闭
TF_REUSE_SOCKET允许套接字句柄再次做为客户机套接字用于AcceptEx中
T F _ U S E _ D E FA U LT _ W O R K E R 表明传输应该在系统默认线程场景中进。特别有利于长文件传输
T F _ U S E _ S Y S T E M _ T H R E A D 表明传输应该在系统线程场景中进行。同样有利于长文件传输
T F _ U S E _ K E R N E L _ A P C 表明“内核异步进程调用”(A P C)应该对文件传输进行处理。如果把指定文件读入缓冲区只需要一次读取,该标志便可提供一个重要的性能提升
T F _ W R I T E _ B E H I N D 表明Tr a n s m i t F i l e应该在无须远程系统对所有的数据进行收到确认的情况下结束
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值