发布时间 : 星期四 文章WINDOW SOCKET 学习笔记更新完毕开始阅读002a8709bb68a98271fefadf
if(SOCKET_ERROR==nreadlen) {
//失败处理 }
7 send()函数的使用
send()函数和WSASend()函数用于发送数据。Send()函数声明如下: int send(){
SOCKET s,
Const char FAR* buf, int len, int flags };
Flags参数影响该函数的行为,该参数可以为0,表示没有特殊行为,MSG_DONTRAOUTE标志要求传输层不要将数据路由出去;MSG_OOB标志表示该数据应该被外带发送。 当该函数调用成功,则会返回实际发送的字节数,当该函数调用失败时,返回SOCKET_ERROR。 例子如下: SOCKET s; Char buf[128]; Int retval;
Strcpy(buf,”send data”);
Retval=send(s,buf,strlen(buf,0)); If(retval==SOCKET_ERROR) {
//失败处理 }
8 closesocket()函数
closesocket()函数实现关闭套接字,释放所占资源。该函数声明如下: int closesocket (
SOCKET s );
当释放套接字后,在使用以释放套接字进行函数调用,则会失败,并返回WSAENOTSOCKE错误
9 shutdown()函数
shutdown()函数用于通知对方不在发送数据或不在接受数据,或者不在发送也不接受数据
该函数声明如下: Int shutdown(
SOCKET s, Int how );
How: 如果该参数为SD_RECEIVE则表示不允许再调用接受数据函数;如果该参数为SE_SEND,则表示不允许再调用发送数据函数;如果该参数为SD_BOTH,则表示不允许调用
发送数据函数和接受数据函数。 10 connect()函数
connect函数实现连接服务器功能。函数声明如下: int connect(
SOCKET s,
Const structaddr FAR* name, Int namelen );
当该函数调用成功时,该函数返回0;函数调用失败返回SOCKET_ERROR. 实例代码: SOCKET s;
u_long serverip; u_short serverport; int retval;
SOCKETADDR_IN servaddr; Servaddr.sin_family=AF_INET;
Servaddr.sin_addr.=htonl(serverip); Servaddr.sin_port=htons(serverport); Int nserlen=sizeof(servaddr);
Retval=connect(s,(LPSOCKADDR)&servaddr,nserlen);
具体函数的使用(udp套接字编程)
对于TCP和UDP编程来说,UDP是面向无连接的,其最重要的不同点就是客户端和服务器不用建立连接。
具体表现在在UDP程序中不用调用listen()函数和accpet函数等待客户端的连接,只需等待接受数据和发送数据 1 recvfrom()函数
recvfrom()函数和WSARecvfrom()函数用于接受数据 int recvfrom(
SOCKET s, Char FAR* buf, Int len, Int flags,
Struct sockaddr FAR* from, Int FAR* fromlen, ); 2
sendto()函数
sendto()函数与WSASendto()函数实现发送数据 int sendto(
SOCKET s,
Const char FAR* buf, Int flags,
Const struct sockaddr FAR* to, Int tolen );
套接字选项
创建套接字后,通过套接字选项对其各种属性进行设定,就可以对套接字的行为产生影响
1 getsockopt()函数
getsocketopt()函数用于获取套接字选项信息 函数声明如下: Int getsocketopt(
SOCKET s, Int level, //选项级别,有SOL_SOCKET何IPPROTO_TCP Int optname,//套接字选项名称
Char* optval,//接受数据缓冲区,该参数返回套接字选项名称对应值
Int FAR* optlen//缓冲区大小 );
该函数调用成功,则返回值为0,如果调用失败,则返回SOCKET_ERROR。 2 setsocketopt()函数
setsocketopt函数用于设置套接字选项。声明如下: int setsocketopt(
SOCKET s, Int level, Int optname,
Const char FAR* optval; Int optlen );
该函数调用成功,则返回值为0,如果调用失败,则返回SOCKET_ERROR。
套接字的模式和I/.O模型
1阻塞模式是指套接字在执行操作时,调用函数在没有完成操作之前不会立即返回的工作模式,阻塞模式的套接字用于少量数据接受和发送的简单网络程序开发 2 非阻塞模式是指套接字在执行操作时,调用的函数不管操作是否完成都会立即返回的工作模式,非阻塞套接字在处理同事建立的多个连接,发送和接受的数据量不均匀,时间不定等方面具有优势。
阻塞模式 在阻塞模式的套接字上,调用任何一个WINDOWS SOCKETS API都会耗费不确定的等待时间。
大多数WINDOWS SOCKETS 程序使用“生产者——消费者”模型 在程序中“生产者”读入数据,“消费者”根据需求对读入数据进行处理。通常生产者和消费者存在于两个线程中,当生产者完成读入数据时,使用线程同步机制,使消费者对数据进行处理。
“生产者——消费者”模型并不能改变阻塞套接字在调用WINDOWS SOCKETS API 函数时对线程的阻塞状态。但是该模式使应用程序可以在阻塞线程之外的线程执行其他的事情。 ? 设置套接字的阻塞模式
当使用socket()函数和WSASocket()函数创建套接字时,默认的套接字都是阻塞的。 同时在WINDOWS SOCKETS API函数中并不是所有的函数都会阻塞。 如bind()函数和listen()函数。 但对于
1 输入输出操作
3 接受和外出连接操作 都会阻塞线程
非阻塞模式
? 把套接字设置为非阻塞模式,即通知系统内核:在调用WINDOWS SOCKETS API时,不
要让线程睡眠,而是让函数立即返回。在返回时,该函数返回一个错误代码。即WSAEWOULDBLOCK错误代码。 ? 设置套接字的非阻塞模式
即:在创建套接字之后,通过调用ioctlsocket()函数,将该套接字设置为阻塞模式。 函数的第一个参数———是套接字。
函数第二个参数————是设置为FIONBIO
函数第三个参数————设置为unsinged long 类型的非零值。 使用范例:
SOCKET s;
Usingned long u1=1; Int nret;
s=socket(AF_INET,SOCK_STREAM,0);
nret =ioctlsocket(s,FIONBIO,(usigned long *)&u1); if(nret==SOCKET_ERROR){ //设定套接字失败 }
套接字设定为非阻塞模式后,在调用函数时,调用函数会立即返回。大多数情况下,这些函数调用都会调用失败,并返回WSAEWOULDBLOCK错误代码。通常,应用程序需要重复调用该函数,直到获得成功返回代码。
阻塞模式套接字使用比较复杂,要对收到的WSAEWOULDBLOCK错误进行处理。通常情况下,可以考虑使用套接字的“I/O模型”,他有助于应用程序通过异步方式,同时对一个或者多个套接字的同学加以管理。