int WSAGetLastError(void );错误值请自己阅读Winsock2.h。
#define h_errno WSAGetLastError()
u_long htonl(u_long hostlong);3、将unsigned long数从网络字节顺序转换位主机字节顺序,是上面函数的逆函数。
举例:htonl(0)=0
htonl(80)= 1342177280
u_long ntohl(u_long netlong);4、将主机的unsigned short值转换为网络字节顺序(16位):原因同2:
举例:ntohl(0)=0
ntohl(1342177280)= 80
u_short htons(u_short hostshort);5、将unsigned short数从网络字节顺序转换位主机字节顺序,是上面函数的逆函数。
举例:htonl(0)=0
htonl(80)= 20480
u_short ntohs(u_short netshort);6、将用点分割的IP地址转换位一个in_addr结构的地址,这个结构的定义见笔记(一),实际上就是一个unsigned long值。计算机内部处理IP地址可是不认识如192.1.8.84之类的数据。
举例:ntohs(0)=0
ntohsl(20480)= 80
unsigned long inet_addr( const char FAR * cp );如果发生错误,函数返回INADDR_NONE值。
举例:inet_addr("192.1.8.84")=1409810880
inet_addr("127.0.0.1")= 16777343
char FAR * inet_ntoa( struct in_addr in );这样addr的值就变为127.0.0.1。
举例:char * ipaddr=NULL;
char addr[20];
in_addr inaddr;
inaddr. s_addr=16777343;
ipaddr= inet_ntoa(inaddr);
strcpy(addr,ipaddr);
int getsockname(SOCKET s, struct sockaddr FAR * name, int FAR * namelen );9、获取与套接字相连的端地址结构:
s为套接字
name为函数调用后获得的地址值
namelen为缓冲区的大小。
int getpeername(SOCKET s, struct sockaddr FAR * name, int FAR * namelen );10、获取计算机名:
s为套接字
name为函数调用后获得的端地址值
namelen为缓冲区的大小。
int gethostname( char FAR * name, int namelen );11、根据计算机名获取主机地址:
name是存放计算机名的缓冲区
namelen是缓冲区的大小
用法:
char szName[255];
memset(szName,0,255);
if(gethostname(szName,255)==SOCKET_ERROR)
{
//错误处理
}
返回值为:szNmae="xiaojin"
struct hostent FAR * gethostbyname( const char FAR * name );Winsock 的I/O操作:
name为计算机名。
用法:
hostent * host;
char* ip;
host= gethostbyname("xiaojin");
if(host->h_addr_list[0])
{
struct in_addr addr;
memmove(&addr, host->h_addr_list[0],4);
//获得标准IP地址
ip=inet_ ntoa (addr);
}
返回值为:hostent->h_name="xiaojin"
hostent->h_addrtype=2 //AF_INET
hostent->length=4
ip="127.0.0.1"
int select( int nfds, fd_set FAR * readfds, fd_set FAR * writefds,◆先来看看涉及到的结构的定义:
fd_set FAR *exceptfds, const struct timeval FAR * timeout );
#define FD_SETSIZE 64?fd_count为已设定socket的数量
typedef struct fd_set {
u_int fd_count; /* how many are SET? */
SOCKET fd_array[FD_SETSIZE]; /* an array of SOCKETs */
} fd_set;
struct timeval {tv_sec为时间的秒值。
long tv_sec; /* seconds */
long tv_usec; /* and microseconds */
};
fd_set fdread;
//FD_ZERO定义
// #define FD_ZERO(set) (((fd_set FAR *)(set))->fd_count=0)
FD_ZERO(&fdread);
FD_SET(s,&fdread); //加入套接字,详细定义请看winsock2.h
if(select(0,%fdread,NULL,NULL,NULL)>0
{
//成功
if(FD_ISSET(s,&fread) //是否存在fread中,详细定义请看winsock2.h
{
//是可读的
}
}
◆I/O操作函数:主要用于获取与套接字相关的操作参数。
int ioctlsocket(SOCKET s, long cmd, u_long FAR * argp );s为I/O操作的套接字。
//确定套接字自动读入的数据量3、WSAAsynSelect模型:
#define FIONREAD _IOR(''''f'''', 127, u_long) /* get # bytes to read */
//允许或禁止套接字的非阻塞模式,允许为非0,禁止为0
#define FIONBIO _IOW(''''f'''', 126, u_long) /* set/clear non-blocking i/o */
//确定是否所有带外数据都已被读入
#define SIOCATMARK _IOR(''''s'''', 7, u_long) /* at oob mark? */
int WSAAsyncSelect( SOCKET s, HWND hWnd, u_int wMsg, long lEvent);s为需要事件通知的套接字
#define FD_READ_BIT 0用法:要接收读写通知:
#define FD_READ (1 << FD_READ_BIT)
#define FD_WRITE_BIT 1
#define FD_WRITE (1 << FD_WRITE_BIT)
#define FD_OOB_BIT 2
#define FD_OOB (1 << FD_OOB_BIT)
#define FD_ACCEPT_BIT 3
#define FD_ACCEPT (1 << FD_ACCEPT_BIT)
#define FD_CONNECT_BIT 4
#define FD_CONNECT (1 << FD_CONNECT_BIT)
#define FD_CLOSE_BIT 5
#define FD_CLOSE (1 << FD_CLOSE_BIT)
int nResult= WSAAsyncSelect(s,hWnd,wMsg,FD_READ|FD_WRITE);取消通知:
if(nResult==SOCKET_ERROR)
{
//错误处理
}
int nResult= WSAAsyncSelect(s,hWnd,0,0);当应用程序窗口hWnd收到消息时,wMsg.wParam参数标识了套接字,lParam的低字标明
#define WSAEVENT HANDLE该函数的返回值为一个事件对象句柄,它具有两种工作状态:已传信(signaled)和未传信
#define LPWSAEVENT LPHANDLE
WSAEVENT WSACreateEvent( void );
int WSAEventSelect( SOCKET s,WSAEVENT hEventObject,long lNetworkEvents );s为套接字
BOOL WSAResetEvent( WSAEVENT hEvent );
Hevent为事件对象
成功返回TRUE,失败返回FALSE。
d、等待网络事件来触发事件句柄的工作状态:
DWORD WSAWaitForMultipleEvents( DWORD cEvents,
const WSAEVENT FAR * lphEvents, BOOL fWaitAll,
DWORD dwTimeout, BOOL fAlertable );
lpEvent为事件句柄数组的指针
cEvent为为事件句柄的数目,其最大值为WSA_MAXIMUM_WAIT_EVENTS
fWaitAll指定等待类型:TRUE:当lphEvent数组重所有事件对象同时有信号时返回;
FALSE:任一事件有信号就返回。
dwTimeout为等待超时(毫秒)
fAlertable为指定函数返回时是否执行完成例程
对事件数组中的事件进行引用时,应该用WSAWaitForMultipleEvents的返回值,减去
预声明值WSA_WAIT_EVENT_0,得到具体的引用值。例如:
nIndex=WSAWaitForMultipleEvents(…);
MyEvent=EventArray[Index- WSA_WAIT_EVENT_0];
e、判断网络事件类型:
int WSAEnumNetworkEvents( SOCKET s,
WSAEVENT hEventObject, LPWSANETWORKEVENTS lpNetworkEvents );
s为套接字
hEventObject为需要重设的事件对象
lpNetworkEvents为记录网络事件和错误代码,其结构定义如下:
typedef struct _WSANETWORKEVENTS {
long lNetworkEvents;
int iErrorCode[FD_MAX_EVENTS];
} WSANETWORKEVENTS, FAR * LPWSANETWORKEVENTS;
f、关闭事件对象句柄:
BOOL WSACloseEvent(WSAEVENT hEvent);
调用成功返回TRUE,否则返回FALSE。