2008年12月24日星期三

winsock 的一些函数

[来自 http://liubin.itpub.net/ 村长的麦田]

与socket有关的一些函数介绍

1、读取当前错误值:每次发生错误时,如果要对具体问题进行处理,那么就应该调用这个函数取得错误代码。

int WSAGetLastError(void );

#define h_errno WSAGetLastError()

错误值请自己阅读Winsock2.h。

2
、将主机的unsigned long值转换为网络字节顺序(32位):为什么要这样做呢?因为不同的计算机使用不同的字节顺序存储数据。因此任何从Winsock函数对IP地址和端口号的引用和传给Winsock函数的IP地址和端口号均时按照网络顺序组织的。

u_long htonl(u_long hostlong);

举例:htonl(0)=0

htonl(80)= 1342177280

3、将unsigned long数从网络字节顺序转换位主机字节顺序,是上面函数的逆函数。

u_long ntohl(u_long netlong);

举例:ntohl(0)=0

ntohl(1342177280)= 80

4、将主机的unsigned short值转换为网络字节顺序(16位):原因同2:

u_short htons(u_short hostshort);

举例:htonl(0)=0

htonl(80)= 20480

5、将unsigned short数从网络字节顺序转换位主机字节顺序,是上面函数的逆函数。

u_short ntohs(u_short netshort);

举例:ntohs(0)=0

ntohsl(20480)= 80

6、将用点分割的IP地址转换位一个in_addr结构的地址,这个结构的定义见笔记(一),实际上就是一个unsigned long值。计算机内部处理IP地址可是不认识如192.1.8.84之类的数据。

unsigned long inet_addr( const char FAR * cp );

举例:inet_addr("192.1.8.84")=1409810880

inet_addr("127.0.0.1")= 16777343

如果发生错误,函数返回INADDR_NONE值。

7
、将网络地址转换位用点分割的IP地址,是上面函数的逆函数。

char FAR * inet_ntoa( struct in_addr in );

举例:char * ipaddr=NULL;

char addr[20];

in_addr inaddr;

inaddr. s_addr=16777343;

ipaddr= inet_ntoa(inaddr);

strcpy(addr,ipaddr);

这样addr的值就变为127.0.0.1。
注意意不要修改返回值或者进行释放动作。如果函数失败就会返回NULL值。

8
、获取套接字的本地地址结构:

int getsockname(SOCKET s, struct sockaddr FAR * name, int FAR * namelen );

s为套接字

name为函数调用后获得的地址值

namelen为缓冲区的大小。

9、获取与套接字相连的端地址结构:

int getpeername(SOCKET s, struct sockaddr FAR * name, int FAR * namelen );

s为套接字

name为函数调用后获得的端地址值

namelen为缓冲区的大小。

10、获取计算机名:

int gethostname( char FAR * name, int namelen );

name是存放计算机名的缓冲区

namelen是缓冲区的大小

用法:

char szName[255];

memset(szName,0,255);

if(gethostname(szName,255)==SOCKET_ERROR)

{

//错误处理

}

返回值为:szNmae="xiaojin"

11、根据计算机名获取主机地址:

struct hostent FAR * gethostbyname( const char FAR * name );

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"

Winsock 的I/O操作:

1
、 两种I/O模式

  • 阻塞模式:执行I/O操作完成前会一直进行等待,不会将控制权交给程序。套接字 默认为阻塞模式。可以通过多线程技术进行处理。
  • 非阻塞模式:执行I/O操作时,Winsock函数会返回并交出控制权。这种模式使用 起来比较复杂,因为函数在没有运行完成就进行返回,会不断地返回 WSAEWOULDBLOCK错误。但功能强大。

为了解决这个问题,提出了进行I/O操作的一些I/O模型,下面介绍最常见的三种:

2
、select模型:

  通过调用select函数可以确定一个或多个套接字的状态,判断套接字上是否有数据,或
者能否向一个套接字写入数据。

int select( int nfds, fd_set FAR * readfds, fd_set FAR * writefds,

fd_set FAR *exceptfds, const struct timeval FAR * timeout );

◆先来看看涉及到的结构的定义:
a
、 d_set结构:

#define FD_SETSIZE 64?

typedef struct fd_set {

u_int fd_count; /* how many are SET? */

SOCKET fd_array[FD_SETSIZE]; /* an array of SOCKETs */

} fd_set;

fd_count为已设定socket的数量
fd_array
为socket列表,FD_SETSIZE为最大socket数量,建议不小于64。这是微软建
议的。

B
、timeval结构:

struct timeval {

long tv_sec; /* seconds */

long tv_usec; /* and microseconds */

};

tv_sec为时间的秒值。
tv_usec
为时间的毫秒值。
这个结构主要是设置select()函数的等待值,如果将该结构设置为(0,0),则select()函数
会立即返回。

◆再来看看select函数各参数的作用:

  1. nfds:没有任何用处,主要用来进行系统兼容用,一般设置为0。
  2. readfds:等待可读性检查的套接字组。
  3. writefds;等待可写性检查的套接字组。
  4. exceptfds:等待错误检查的套接字组。
  5. timeout:超时时间。
  6. 函数失败的返回值:调用失败返回SOCKET_ERROR,超时返回0。

readfds、writefds、exceptfds三个变量至少有一个不为空,同时这个不为空的套接字组
种至少有一个socket,道理很简单,否则要select干什么呢。 举例:测试一个套接字是否可读:

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操作的套接字。
cmd
为对套接字的操作命令。
argp
为命令所带参数的指针。

常见的命令:

//确定套接字自动读入的数据量

#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? */

3、WSAAsynSelect模型:
WSAAsynSelect
模型也是一个常用的异步I/O模型。应用程序可以在一个套接字上接收以
WINDOWS
消息为基础的网络事件通知。该模型的实现方法是通过调用WSAAsynSelect函
数 自动将套接字设置为非阻塞模式,并向WINDOWS注册一个或多个网络时间,并提供一
个通知时使用的窗口句柄。当注册的事件发生时,对应的窗口将收到一个基于消息的通知。

int WSAAsyncSelect( SOCKET s, HWND hWnd, u_int wMsg, long lEvent);

s为需要事件通知的套接字
hWnd
为接收消息的窗口句柄
wMsg
为要接收的消息
lEvent
为掩码,指定应用程序感兴趣的网络事件组合,主要如下:

#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_READFD_WRITE);

if(nResult==SOCKET_ERROR)

{

//错误处理

}

取消通知:

int nResult= WSAAsyncSelect(s,hWnd,0,0);

当应用程序窗口hWnd收到消息时,wMsg.wParam参数标识了套接字,lParam的低字标明
了网络事件,高字则包含错误代码。

4
、WSAEventSelect模型
WSAEventSelect
模型类似WSAAsynSelect模型,但最主要的区别是网络事件发生时会被发
送到一个事件对象句柄,而不是发送到一个窗口。

使用步骤如下:
a
、 创建事件对象来接收网络事件:

#define WSAEVENT HANDLE

#define LPWSAEVENT LPHANDLE

WSAEVENT WSACreateEvent( void );

该函数的返回值为一个事件对象句柄,它具有两种工作状态:已传信(signaled)和未传信
(nonsignaled)
以及两种工作模式:人工重设(manual reset)和自动重设(auto reset)。默认未
未传信的工作状态和人工重设模式。

b
、将事件对象与套接字关联,同时注册事件,使事件对象的工作状态从未传信转变未
已传信。

int WSAEventSelect( SOCKET s,WSAEVENT hEventObject,long lNetworkEvents );

s为套接字
hEventObject
为刚才创建的事件对象句柄
lNetworkEvents
为掩码,定义如上面所述

c
、I/O处理后,设置事件对象为未传信

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

2008年12月23日星期二

今生 只借你一夜

文/天国雪莲(银杏树club.xilu.com/ginkgotree)

 

和大多数上网聊天的女人一样,她上网聊天的理由也是寂寞无聊。
一个住校高一的儿子,一个常年住在外省的老公。她,一个42岁就提前养的政府公务员。
于是,在她聊天的半年后,她认识了他。
网上叫她如鱼得水,散发着女人的魅力与妖娆。网上叫她随心所欲,绽放着封闭几十年的玫瑰。
尽管嘻闹着,荡漾着,但她从来就没有把网上的缠缠绵绵当回事。因为,她心灵的地带,还没有人触摸过。直到遇到他,那时,她感觉到了天崩地裂。
他在她的QQ好友里,是一个始终被自己忽略的人物。就像鸡肋一样,是个不暗情调的男人。
也许那天她实在没有人聊了,才打开他的窗口。无聊的时候,她只发图片。那天,她刚好在群聊中截获一个图片,嫩绿的背景中,两只翩翩飞舞而又在忙里偷闲接吻的花色蝴蝶,旁边写着:"今生,只借你一夜"。她就把这个图片发给他。他回了一个微笑和一片红心。
你今天的胆子好大啊!她问道。对不起,今天我喝了不少的酒。他发过来一个害羞的表情。又说:如果真的有那么一天,我绝对的接受!
听了这个从来不会用挑逗的语言和自己聊天的男人的话,她的脸色潮红了。
你知道这两只蝴蝶的姓氏名谁吗?她问。
他半天没有言语。一会发过来一首曲子,竟然是小提琴曲《梁祝》,还有一行字:一个姓梁,一个姓祝......
那一刻,她久筑的长城轰然倒地......
好久,她默默地对着屏幕,听着音乐,流着泪水。长久以来的心灵地带竟被这个从来没有谋过面的男人,给拨动了。
她瞬间打开视频,她看见了噙着泪的他和流着泪她自己。
这是个俊郎的男人,小平头显得十分的精神,年龄比她小。一问知道竟然小她5岁。她笑了喊他:弟弟好!之后就逼着他叫她姐姐。他沉吟了半天,也没喊出来。为什么?他回答:不习惯。
这个男人竟懂音乐!之后的日子,他们边聊天,边听音乐。
那些日子,她都是隐身上线,直到有一天她的好友铺天盖地地喊她为什么不上线时,她才知道,她只和他聊天,竟有一个月有余。
网恋了耶!她警告自己,决不网恋,是她最初上网时给自己的诺言。诺言一旦打破,就是万劫不复,逝水难收了。

两个人的见面是不可避免的。
这是个喜欢倾听的男人,只喜欢听她的述说的男人。她喜欢看他亮晶晶的眼睛,她笑了,他的眼睛就是弯月;她哭了,他的眼睛就是深泉......
他们拥抱一起的时候,他笨拙地叫了声:姐姐......她竟回叫了他一声:哥哥......他们聊着各自的家庭,聊着单位和生活中的趣事,发现彼此的看法是那么的相同。
他说,他好久没有和人说这么多的话。她说,她也好久没有和人这样的相诉。
原来,他们都需要温暖和倾诉啊。
他们在相互寻找彼此的温暖......

他们再次拥有的时候,是他们第二次见面的日子。
那天,她好像有所准备似的,在他们都已醉意朦胧时候,不知不觉就到酒店的楼上开了房。他发现她竟然从包里拿出一包套子,他笑了:你准备的好充分啊......
他战抖着紧紧地抱着她,久久不肯松开。她等着他,等着为他绽放,他却没有回应。
为什么?她问。
不知道。好长时间,我和老婆没有这个了?
多久?
三年......
她叹道:怎么我们就这么相似。然后,她搂过他,轻拥他入怀。轻轻地拍着他的肩头说:不要急,一切都会好的。她给他讲着她的故事,从童年、青年直到现在。
在她将要睡去的时候,他一下把她搂住......
他们对望着,擦拭彼此的汗水,他说:今天我才知道,女人竟然是这么好!她的泪水再次涌出,一下又把他搂在怀里:就让我们在今后的日子彼此慰籍好吗?
让我们永远这样好吗?他也问。
11
点了,他说,我该回家了。我老婆从来不允许我在外面过夜。她心酸,但还是服从了他。
爱,更多的时候是服从。

以后的日子,他们都从网上走下来,进入到现实的婚外恋中。每天的一个电话是他们的约定。经常她先给他打过去,就马上挂掉。她非常体谅他,体谅他的工作和地位。他有空就一定回,有时不在办公室,也会在匆忙中回的。她善解人意,这时她从来不缠着他多聊。之后,脑子里是他忙碌的身影和匆忙的脚印。常常在她等待的过程中,她会拿着手机在房间里走来走去,等着他的声音。她从不在休息节假日打他的电话,她知道他有个很敏感警犬一样的老婆。
爱上一个人,好辛苦啊!

女人往往比男人首先陷入情网。为了不再整天想他,她到社区做了义工,帮助需要照顾的老人。老人把她称作好姑娘。那时,她的心一颤,羞愧难当。他们从来都不想涉入彼此的家庭,没有承诺,没有誓言。
其实,她一直想要他一夜,一个属于她的一个夜晚。哪怕第二天就天翻地覆,她也想要。一年中,他们每个月都要到宾馆做爱,她用自己的身份证登记,她不想叫他暴露,对于她来说,他的前途和平安比她的生命都重要。
她知道他很疼她,她曾经逼着他叫他说:我爱你!他没有说。她就哭了。这很重要吗?他问。她诧异了。
在以后的日子里,她感受着来自他的关怀和疼爱。之初,他们开始在网上交往时,她就感觉到了。那时,他们还没有见面,她说自己的脚被新皮鞋磨破了,他马上打开视频,只叫她把脚抬起来给他看看。
她知道,这个时候他在办公室里,看一个女人的脚有多么的危险。她拒绝了。他好像生气了,决绝地一次次打开视频。她举着脚,心里翻腾着的是幸福。
有种爱,是不需要用言语表达的。

秋天来的时候,是他们相识整整一年的时间。他们都喜欢秋天的忧郁和成熟,做了一年的隐形情人,他们从来没有一起去到外面玩过,享受着大自然的风光,这就是隐形情人的无奈吧。她多想和他踏着松软的落叶,相拥相依,诉说衷肠......他们做不到,他们的城市太小了,到处都是熟人。他们就在床上幻想着,一起去外地,上西藏,游海南......也只是幻想,因为他们都明白,越是风景名胜的地方,遇到熟人的几率越高。
她最多的时候是不甘心!
那天,他告诉她,他去开会,就在省城,现在已经上火车了。她放下电话,心仿佛一下被掏空,还有一丝丝的疼痛。那些天,想他就给他发信息,他在外面,没有老婆的眼睛,她就尽情地发了一条条缠绵的信息。可恨的他没有给她一条这样的信息。到了每天通话的时候,是她最难傲的时刻。她一遍遍拨他的电话,不等接通,她就挂断,一次次,她感觉要崩溃了。
睡梦中,她醒了,竟是冷泪两行。第二天,她登上省城的列车,寻找她期待的一夜......

刚要退房的他接到她的电话就到火车站接她来了,他们像普通同事一样走在省城的街道上。关上宾馆房门的瞬间,他们翻滚到床上,之后就是地上......
你知道吗,我等这一夜,足足等了一年的时间。她的嘴唇嗅着他的脸。
对不起,由于有很多的无奈,我......
她捂住他的嘴,说,不要和你的爱人说对不起,永远不要。
这一夜,她紧紧地搂住他的后背,生怕他瞬间就抽身。
凌晨3点,他的电话突然骤响:老公啊,你单位的人都回来了,你怎么还没有回来啊?我想了一个晚上怎么想怎么觉得你现在是和一个女人在一起,是不是?
没有啊,你想什么哪!他的声音颤抖着。
没有就马上给我回来,就坐3.50的火车,要不然你就有问题,快点啊!
是,马上......他放下电话,搬过她的脸:对不起,我得马上回去,我怕她再次割腕。我们不能一起走的,说不定遇上什么熟人......
她佯装不在乎什么,强装笑脸,下地给他热了一袋牛奶:空肚子很难受的。他离开时再次抱紧她,她躲开他:没什么的,你快走吧。她转过身,她不愿意叫他看见,她的泪水......
房锁只是轻轻地合上,却震得她心痛。她把剩下的那大半瓶红酒一起喝下,天旋地转,想哭却没有眼泪。
"
网上一个梦/网上你的温柔/我就犯了错/网上的情缘/也卿卿我我/爱一场梦一场/谁能躲得过......"结束吧,结束吧,谁能躲得过......之后,她把手机卡拽下,扔到了窗外。
外面,晨光正放......

2008年12月22日星期一

一个老色狼送给小色狼的40条忠告

1.当她要你请她吃饭的时候,你不妨长时间注视她,如果她表现出来的不是乖巧和温情,那你就别破费。
2.
你在决定追一个女人的时候,先想想自己能不能在她面前保持本色,否则别去委屈自己。-
3.
一等色狼爱才女,二等色狼爱淑女,三等色狼爱美女,四等色狼爱妓女。
4.
与她上街许多次,她一直阻止你为她花钱并不时问你饿不饿渴不渴累不累,并且你由衷感动的话,则你应该考虑娶她。
5.
女人的自尊心比超薄丝袜还脆弱,很多时候你太在乎她的自尊,她就可能不在乎你的自尊,她要变成慈禧的话,你别当李莲英。
6.
爱撒谎的美女不是女人而是精液容器,别太在意。
7.
色狼的最高境界是专一,滥情是菜鸟无能的表现。
8.
与其手捧玫瑰西装革履的站在楼下等她,不如让她看到你在运动场上、篮球架下如何生龙活虎。
9.
多吻她的额头和手背,吻她不敏感的地方,比吻她敏感的地方更能让她有感觉。
10.
爱情 比荒原还残酷。爱情 的快乐有多大,伤口就有多大,但你既然想追她,就不要怕痛苦,否则自个儿sy去好了。
11.
色狼完全没理由为自己是狼而忘形,记住女人是老虎,老虎比狼厉害。
12.
别吃她吃剩的饭菜,别谈她谈厌的话题。
13.
兜里揣一百都为她花光的效果,比揣一万为她花一千的效果强几倍。
14.
女人的承诺和豪言壮语常不及男人的一半可靠。
15.
她面对孕妇与儿童时的表现常证明她对你的感情深到什么程度。
16.
男人去酒吧歌厅找刺激,跟狗翻垃圾堆找食物吃一样,要想做真正的色狼,就别去泡吧K歌。
17.
随着装嫩的女人是白骨精,但你也别当孙悟空。
18.
女人是用来哄的,不是用来骂的。
19.
女人用两个极端的方式管你索要宽厚与温情:小鸟依人,歇斯底里。
20.
对温柔聪明的女人而言,一束百合比999朵玫瑰更有说服力。
21.
适时讲些黄色笑话,经常从背后抱住她轻吻。
22.
女人经常迟到十分钟以上或不来,并说一些你将信将疑的理由,那你不妨考虑和她分手。
23.
如果女人看你的时候眼睛从来没有亮晶晶过,那绝对是你的失败。
24.
游刃有余在多个男人之间周旋的女人可操不可信。
25.
惩治超级自恋不可理喻的女人的最好方式,是直接了当地指出她的缺点,别在乎她的咆哮与掉头离去。
26.
在你无法识破女人假装高潮之前,你还是别自诩成熟。
27.
别对女人期望太高,没有极品好女人,但有极品坏女人。
28.
女人时时对你任性、挑剔、冷淡、拒绝却还口口声声说爱你的时候,她只不过是在压榨你利用你。 [幽默家 http://www.efunster.com]
29.
尽量欣赏一丝不挂的她,而不是用情趣内衣装潢起来的她。
30.
晚上揣把刀走路去接她,比开奔驰宝马去接她更能让她感动。
31.
对女人要多用心去感觉,少用龟头思考。
32.
不会凶狠的色狼必不会温柔。
33.
色狼就是色狼,不该披上羊皮,别去刻意表现绅士风度,营造什么浪漫―――那样你只能追悼不懂事的黄毛丫头。解除外挂原生态一些反而更有魅力。
34.
发嗲是女人的温柔一刀。
35.
在女人眼中,你的袜子就是你的心灵,你的内裤就是你的精神----保证你的袜子和内裤干干净净是很有必要的。
36.
叫嚣女权的女人是空酒瓶。
37.
在成熟的女人眼中,男人玩性格跟婴儿玩小鸡鸡类似。
38.
女人爱钻石与爱情 无关。
39.
要警惕来回变换发型的女人。
40.
判断一个女孩子能不能成为你的女友的最好的方法,就是请她去看一部恐怖片。