WinSock之基础API

转载 2006年05月18日 17:58:00

WinSock之基础API- -

Tagaccpet,connect,                                          

 

5.1.1 accept()

 

简述:

 

  在一个套接口接受一个连接。

 

  #include <winsock.h>

 

 

  SOCKET PASCAL FAR accept( SOCKET s, struct sockaddr FAR* addr,

 

 

  int FAR* addrlen);

 

  s:套接口描述字,该套接口在listen()后监听连接。

 

 

  addr:(可选)指针,指向一缓冲区,其中接收为通讯层所知的连接实体的地址。Addr参数的实际格式由套接口创建时所产生的地址族确定。

 

  addrlen:(可选)指针,指向存有addr地址长度的整形数。

 

注释:

 

 

  本函数从s的等待连接队列中抽取第一个连接,创建一个与s同类的新的套接口并返回句柄。如果队列中无等待连接,且套接口为阻塞方式,则accept()阻塞调用进程直至新的连接出现。如果套接口为非阻塞方式且队列中等待连接,则accept()返回一错误代码。已接受连接的套接口不能用于接受新的连接,原套接口仍保持开放。

 

  addr参数为一个返回参数,其中填写的是为通讯层所知的连接实体地址。addr参数的实际格式由通讯时产生的地址族确定。addrlen参数也是一个返回参数,在调用时初始化为addr所指的地址空间;在调用结束时它包含了实际返回的地址的长度(用字节数表示)。该函数与SOCK_STREAM类型的面向连接的套接口一起使用。如果addraddrlen中有一个为零NULL,将不返回所接受的套接口远程地址的任何信息。

 

返回值:

 

 

  如果没有错误产生,则accept()返回一个描述所接受包的SOCKET类型的值。否则的话,返回INVALID_SOCKET错误,应用程序可通过调用WSAGetLastError()来获得特定的错误代码。

 

  addrlen所指的整形数初始时包含addr所指地址空间的大小,在返回时它包含实际返回地址的字节长度。

 

错误代码:

 

 

  WSANOTINITIALISED:在使用此API之前应首先成功地调用WSAStartup()

 

  WSAENETDOWNWINDOWS套接口实现检测到网络子系统失效。

 

  WSAEFAULTaddrlen参数太小(小于socket结构的大小)。

 

  WSAEINTR:通过一个WSACancelBlockingCall()来取消一个(阻塞的)调用。

 

  WSAEINPROGRESS:一个阻塞的WINDOWS套接口调用正在运行中。

 

  WSAEINVAL:在accept()前未激活listen()

 

  WSAEMFILE:调用accept()时队列为空,无可用的描述字。

 

  WSAENOBUFS:无可用缓冲区空间。

 

  WSAENOTSOCK:描述字不是一个套接口。

 

  WSAEOPNOTSUPP:该套接口类型不支持面向连接服务。

 

  WSAEWOULDBLOCK:该套接口为非阻塞方式且无连接可供接受。

 

 

参见:

 

  bind(), connect(), listen(), select(), socket(), WSAAsyncSelect().

 

 

 

5.1.2 bind()

 

简述:

 

  将一本地地址与一套接口捆绑。

 

  #include <winsock.h>

 

 

 

  int PASCAL FAR bind( SOCKET s, const struct sockaddr FAR* name,

 

  int namelen);

 

 

  s:标识一未捆绑套接口的描述字。

 

  name:赋予套接口的地址。sockaddr结构定义如下:

 

 

  struct sockaddr{

 

    u_short sa_family;

 

    char sa_data[14];

 

  };

 

 

  namelenname名字的长度。

 

 

注释:

 

  本函数适用于未连接的数据报或流类套接口,在connect()listen()调用前使用。当用socket()创建套接口后,它便存在于一个名字空间(地址族)中,但并未赋名。bind()函数通过给一个未命名套接口分配一个本地名字来为套接口建立本地捆绑(主机地址/断口号)。

 

  Internet地址族中,一个名字包括几个组成部分,对于SOCK_PGRAMSOCK_STREAM类套接口,名字由三部分组成:主机地址,协议号(显式设置为UDPTCP)和用以区分应用的端口号。如果一个应用并不关心分配给它的地址,则可将Internet地址设置为INADDR_ANY,或将端口号置为0。如果Internet地址段为INADDR_ANY,则可使用任意网络接口;在有多种主机环境下可简化编程。如果端口号置为0,则WINDOWS套接口实现将给应用程序分配一个值在10245000之间的唯一的端口。应用程序可在bind()后用getsockname()来获知所分配的地址,但必需注意的是,getsockname()只有在套接口连接成功后才会填写Internet地址,这是由于在多种主机环境下若干种Internet地址都是有效的。

 

  如果一个应用程序需要把端口捆绑到超过10245000范围的特定端口时,比如rsh需要捆绑到任一保留端口,则可如下编程:

 

 

  SOCKADDR_IN sin;

 

  SOCKET s;

 

  u_short alport=IPPORT_RESERVED;

 

  sin.sin_family=AF_INET;

 

  sin.sin_addr.s_addr=0;

 

  for (;;) {

 

    sin.sin_port=htons(alport);

 

    if (bind(s,(LPSOCKADDR)&sin, sizeof(sin))=0) {

 

        /* it worked */

 

    }

 

    if (GetLastError()!=WSAEADDRINUSE) {

 

        /* fail */

 

    }

 

    alport-;

 

    if (alport=IPPORT_RESERVED/2) {

 

        /* failall unassigned reserved ports are */

 

        /* in use. */

 

    }

 

  }

 

 

 

返回值:

 

  如无错误发生,则bind()返回0。否则的话,将返回SOCKET_ERROR,应用程序可通过WSAGetLastError()获取相应错误代码。

 

 

错误代码:

 

  WSANOTINITIALISED:在使用此API之前应首先成功地调用WSAStartup()

 

  WSAENETDOWNWINDOWS套接口实现检测到网络子系统失效。

 

  WSAEADDRINUSE:所定端口已在使用中(参见setoption()中的SO_REUSEADDR选项)。

 

  WSAEFAULTnamelen参数太小(小于sockaddr结构的大小)。

 

  WSAEINPROGRESS:一个阻塞的WINDOWS套接口调用正在运行中。

 

  WSAEAFNOSUPPORT:本协议不支持所指定的地址族。

 

  WSAEINVAL:该套接口已与一个地址捆绑。

 

  WSAENOBUFS:无足够可用缓冲区,连接过多。

 

  WSAENOTSOCK:描述字不是一个套接口。

 

 

参见:

 

  connect(), listen(), getsockname(), setsockopt(), socket(), WSACancelBlockingCall().

 

 

 

5.1.3 closesocket()

 

简述:

 

  关闭一个套接口。

 

 

  #include <winsock.h>

 

 

  int PASCAL FAR closesocket( SOCKET s);

 

 

  s:一个套接口的描述字。

 

 

注释:

 

  本函数关闭一个套接口。更确切地说,它释放套接口描述字s,以后对s的访问均以WSAENOTSOCK错误返回。若本次为对套接口的最后一次访问,则相应的名字信息及数据队列都将被释放。closesocket()的语义受SO_LINGERSO_DONTLINGER选项影响,对比如下:

 

 

选项                间隔    关闭方式    等待关闭与否

 

SO_DONTLINGER       不关心  优雅       

 

SO_LINGER                 强制       

 

SO_LINGER           非零    优雅       

 

 

  若设置了SO_LINGER(亦即linger结构中的l_onoff域设为非零,参见2.44.1.74.1.21各节),并设置了零超时间隔,则closesocket()不被阻塞立即执行,不论是否有排队数据未发送或未被确认。这种关闭方式称为强制失效关闭,因为套接口的虚电路立即被复位,且丢失了未发送的数据。在远端的recv()调用将以WSAECONNRESET出错。

 

  若设置了SO_LINGER并确定了非零的超时间隔,则closesocket()调用阻塞进程,直到所剩数据发送完毕或超时。这种关闭称为优雅的关闭。请注意如果套接口置为非阻塞且SO_LINGER设为非零超时,则closesocket()调用将以WSAEWOULDBLOCK错误返回。

 

  若在一个流类套接口上设置了SO_DONTLINGER(也就是说将linger结构的l_onoff域设为零;参见2.44.1.74.1.21节),则closesocket()调用立即返回。但是,如果可能,排队的数据将在套接口关闭前发送。请注意,在这种情况下WINDOWS套接口实现将在一段不确定的时间内保留套接口以及其他资源,这对于想用所以套接口的应用程序来说有一定影响。

 

 

返回值:

 

  如无错误发生,则closesocket()返回0。否则的话,返回SOCKET_ERROR错误,应用程序可通过WSAGetLastError()获取相应错误代码。

 

 

错误代码:

 

  WSANOTINITIALISED:在使用此API之前应首先成功地调用WSAStartup()

 

  WSAENETDOWNWINDOWS套接口实现检测到网络子系统失效。

 

  WSAENOTSOCK:描述字不是一个套接口。

 

  WSAEINPROGRESS:一个阻塞的WINDOWS套接口调用正在运行中。

 

  WSAEINTR:通过一个WSACancelBlockingCall()来取消一个(阻塞的)调用。

 

  WSAEWOULDBLOCK:该套接口设置为非阻塞方式且SO_LINGER设置为非零超时间隔。

 

 

参见:

 

  accept(), socket(), ioctlsocket(), setsockopt(), WSAAsyncSelect().

 

 

5.1.4 connect()

 

简述:

 

  建立与一个端的连接。

 

 

  #include <winsock.h>

 

 

  int PASCAL FAR connect( SOCKET s, const struct sockaddr FAR* name,

 

  int namelen);

 

 

  s:标识一个未连接套接口的描述字。

 

  name:欲进行连接的端口名。

 

  namelen:名字长度。

 

 

注释:

 

  本函数用于创建与指定外部端口的连接。s参数指定一个未连接的数据报或流类套接口。如套接口未被捆绑,则系统赋给本地关联一个唯一的值,且设置套接口为已捆绑。请注意若名字结构中的地址域为全零的话,则connect()将返回WSAEADDRNOTAVAIL错误。

 

  对于流类套接口(SOCK_STREAM类型),利用名字来与一个远程主机建立连接,一旦套接口调用成功返回,它就能收发数据了。对于数据报类套接口(SOCK_DGRAM类型),则设置成一个缺省的目的地址,并用它来进行后续的send()recv()调用。

 

 

返回值:

 

  若无错误发生,则connect()返回0。否则的话,返回SOCKET_ERROR错误,应用程序可通过WSAGetLastError()获取相应错误代码。对阻塞套接口而言,若返回值为SOCKET_ERROR则应用程序调用WSAGetLsatError()。如果它指出错误代码为WSAEWOULDBLOCK,则您的应用程序可以:

 

  1.select(),通过检查套接口是否可写,来确定连接请求是否完成。或者,

 

  2.如果您的应用程序使用基于消息的WSAAsynSelect()来表示对连接事件的兴趣,则当连接操作完成后,您会收到一个FD_CONNECT消息。

 

 

错误代码:

 

  WSAENOTINITIALISED:在使用此API之前应首先成功地调用WSAStartup()

 

  WSAENETDOWNWINDOWS套接口实现检测到网络子系统失效。

 

  WSAEADDRINUSE:所指的地址已在使用中。

 

  WSAEINTR:通过一个WSACancelBlockingCall()来取消一个(阻塞的)调用。

 

  WSAEINPROGRESS:一个阻塞的WINDOWS套接口调用正在运行中。

 

  WSAEADDRNOTAVAIL:在本地机器上找不到所指的地址。

 

  WSAENOTSUPPORT:所指族中地址无法与本套接口一起使用。

 

  WSAECONNREFUSED:连接尝试被强制拒绝。

 

  WSAEDESTADDREQ:需要目的地址。

 

  WSAEFAULTnamelen参数不正确。

 

  WSAEINVAL:套接口没有准备好与一地址捆绑。

 

  WSAEISCONN:套接口早已连接。

 

  WSAEMFILE:无多余文件描述字。

 

  WSAENETUNREACH:当前无法从本主机访问网络。

 

  WSAENOBUFS:无可用缓冲区。套接口未被连接。

 

  WSAENOTSOCK:描述字不是一个套接口。

 

  WSAETIMEOUT:超时时间到。

 

  WSAEWOULDBLOCK:套接口设置为非阻塞方式且连接不能立即建立。可用select()调用对套接口写,因为select()时会进行连接。

 

 

参见:

 

  accept(), bind(), getsockname(), socket(), select(), WSAAsyncSelect().

 

 

 

5.1.5 getpeername()

 

简述:

 

  获取与套接口相连的端地址。

 

 

  #include <winsock.h>

 

 

  int PASCAL FAR getpeername( SOCKET s, struct sockaddr FAR* name,

 

  int FAR* namelen);

 

 

  s:标识一已连接套接口的描述字。

 

  name:接收端地址的名字结构。

 

  namelen:一个指向名字结构的指针。

 

 

注释:

 

  getpeername()函数用于从端口s中获取与它捆绑的端口名,并把它存放在sockaddr类型的name结构中。它适用于数据报或流类套接口。

 

 

返回值:

 

  若无错误发生,getpeername()返回0。否则的话,返回SOCKET_ERROR,应用程序可通过WSAGetLastError()来获取相应的错误代码。

 

 

错误代码:

 

  WSANOTINITIALISED:在使用此API之前应首先成功地调用WSAStartup()

 

  WSAENETDOWNWINDOWS套接口实现检测到网络子系统失效。

 

  WSAEFAULTnamelen参数不够大。

 

  WSAEINPROGRESS:一个阻塞的WINDOWS套接口调用正在运行中。

 

  WSAENOTCONN 套接口未连接。

 

  WSAENOTSOCK:描述字不是一个套接口。

 

 

参见:

 

  bind(), socket(), getsockname().

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Winsock I/O 模型详解

Winsock共有五种类型的套接字I/O模型,可让Winsock应用程序对I/O进行管理,它们包括: select(选择)、WSAAsyncSelect(异步选择)、WSAEventSelect(事件...
  • windows_nt
  • windows_nt
  • 2014年09月21日 21:31
  • 3326

网络聊天_服务器端(Winsock编程)

// 网络聊天_服务器端.cpp : 定义控制台应用程序的入口点。 //#include "stdafx.h" #include #include #include #pragma commen...
  • huangxiang360729
  • huangxiang360729
  • 2016年04月01日 18:50
  • 292

Winsock基础编程

Winsock编程        Socket的英文原义是“孔”或“插座”。作为BSD UNIX的进程通信机制,取后一种意思。通常也称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄。在In...
  • zhuhuangtianzi
  • zhuhuangtianzi
  • 2014年08月23日 00:09
  • 946

【C++】Winsock套接字编程(TCP/IP协议体系)常用API

鄙人水平浅薄,如有错误,欢迎大神指正 系统环境:Windows10 64位 开发环境:VisualStudio2015 PS:关于本文提供的winsock套接字API,是针对wi...
  • shihoongbo
  • shihoongbo
  • 2016年05月24日 14:21
  • 997

WinSock API编程通用的操作步骤

学习Socket编程,看到 (1) Winsock的打开(使用WSAStartup()来实现) 因为WinSock的服务是以动态链接库形式来实现的,因此必须首先对 WinSock  DLL进行初...
  • u010450926
  • u010450926
  • 2014年05月24日 01:32
  • 1540

WinSock获得本机Ip地址

每次写网络程序都必须编写代码载入和释放winsock库,为了以后方便使用,我们将封装一个CInitSock类来管理Winsock库...
  • loveRooney
  • loveRooney
  • 2014年04月09日 21:18
  • 2280

Windows网络编程学习笔记(1) 编写一个Winsock基本框架

学习Winsock编程时的学习笔记,本章将介绍Winsock基本框架,Winsock 的作用,Winsock的环境设置, WSADATA结构体,不同平台下的Winsock版本,最基本的Winsock框...
  • Raito__
  • Raito__
  • 2016年05月10日 18:45
  • 2058

WinSock编程基础

在上一篇中,我们具体介绍了socket的相关概念,本节将概述套接字规范及操作的一些基础性知识。   一.套接字的一些基础知识 1.Windows通信相关驱动 netio.sys(Network...
  • liujiayu2
  • liujiayu2
  • 2015年06月16日 13:37
  • 626

Winsock API 函数大全

Winsock API 函数大全 3             本系统(WinKing)提供之 Windows So...
  • MEIYOUDAO_JIUSHIDAO
  • MEIYOUDAO_JIUSHIDAO
  • 2013年01月25日 16:11
  • 456

Winsock API学习记录

1、字节排序函数:在计算机网络中,放送端在传输数据之前必须要将用主机字节顺序表示的数据转化为网络字节顺序,然后才能发送数据。在数据接收端,系统要把收到的网络字节顺序的数据转化为主机字节顺序的数据。 (...
  • u010236780
  • u010236780
  • 2015年08月11日 09:55
  • 244
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:WinSock之基础API
举报原因:
原因补充:

(最多只允许输入30个字)