??xml version="1.0" encoding="utf-8" standalone="yes"?>久久精品国内一区二区三区,欧美日韩在线中文字幕,欧美群妇大交群中文字幕http://www.aygfsteel.com/john_yu/category/24348.html正在学习(fn)中:(x)Q?/description>zh-cnWed, 26 Dec 2007 22:37:04 GMTWed, 26 Dec 2007 22:37:04 GMT60常用的MQ命o(h)http://www.aygfsteel.com/john_yu/archive/2007/12/26/170644.htmljohnjohnWed, 26 Dec 2007 09:26:00 GMThttp://www.aygfsteel.com/john_yu/archive/2007/12/26/170644.htmlhttp://www.aygfsteel.com/john_yu/comments/170644.htmlhttp://www.aygfsteel.com/john_yu/archive/2007/12/26/170644.html#Feedback0http://www.aygfsteel.com/john_yu/comments/commentRss/170644.htmlhttp://www.aygfsteel.com/john_yu/services/trackbacks/170644.html最q在配置MQ,C了一些常用的MQ命o(h),如下:

创徏队列理?
crtmqm –q QMgrName
-q是指创徏~省的队列管理器

删除队列理?
dltmqm QmgrName

启动队列理?
strmqm QmgrName
如果是启动默认的队列理器,可以不带其名?

停止队列理?
endmqm QmgrName 受控停止

endmqm –i QmgrName 立即停止

endmqm –p QmgrName 强制停止

昄队列理?
dspmq –m QmgrName

q行MQ命o(h)
runmqsc QmgrName
如果是默认队列管理器Q可以不带其名字

往队列中放消息
amqsput QName QmgrName
如果队列是默认队列管理器中的队列Q可以不带其队列理器的名字

从队列中取出消息
amqsget QName QmgrName
如果队列是默认队列管理器中的队列Q可以不带其队列理器的名字

启动通道
runmqchl –c ChlName –m QmgrName

启动侦听
runmqlsr –t TYPE –p PORT –m QMgrName

停止侦听
endmqlsr -m QmgrName

下面是在MQ环境中可以执行的MQ命o(h)(卛_runmqsc环境下可以敲的命?

定义持久信队?
DEFINE QLOCALQQNAMEQ?DEFPSISTQYESQ?REPLACE

讑֮队列理器的持久信队?
ALTER QMGR DEADQQQNAMEQ?

定义本地队列
DEFINE QLQQNAMEQ?REPLACE

定义别名队列
DEFINE QALIAS(QALIASNAME) TARGQ(QNAME)

q程队列定义
DEFINE QREMOTEQQRNAMEQ?+
RNAMEQAAAQ?RQMNAMEQQMGRNAMEQ?+
XMITQQQTNAMEQ?

定义模型队列
DEFINE QMODELQQNAMEQ?DEFTYPEQTEMPDYNQ?

定义本地传输队列
DEFINE QLOCAL(QTNAME) USAGE(XMITQ) DEFPSIST(YES) +
INITQQSYSTEM.CHANNEL.INITQQ?
PROCESS(PROCESSNAME) REPLACE

创徏q程定义
DEFINE PROCESSQPRONAMEQ?+
DESCRQ?#8216;STRING’Q?
APPLTYPEQWINDOWSNTQ?
APPLICIDQ?#8217; runmqchl -c SDR_TEST -m QM_ TEST’Q?
其中APPLTYPE的值可以是QCICS、UNIX、WINDOWS、WINDOWSNT{?

创徏发送方通道
DEFINE CHANNELQSDRNAMEQ?CHLTYPEQSDRQ?
CONNAMEQ?#8216;100.100.100.215(1418)’Q?XMITQQQTNAMEQ?REPLACE
其中CHLTYPE可以是:(x)SDR、SVR、RCVR、RQSTR、CLNTCONN、SVRCONN、CLUSSDR和CLUSRCVR?

创徏接收斚w道
DEFINE CHANNELQSDR_ TESTQ?CHLTYPEQRCVRQ?REPLACE

创徏服务器连接通道
DEFINE CHANNELQSVRCONNNAMEQ?CHLTYPEQSVRCONNQ?REPLACE

昄队列的所有属?
DISPLAY QUEUEQQNAMEQ?[ALL]

昄队列的所选属?
DISPLAY QUEUEQQNAMEQ?DESCR GET PUT
DISPLAY QUEUEQQNAMEQMAXDEPTH CURDEPTH

昄队列理器的所有属?
DISPLAY QMGR [ALL]

昄q程定义
DISPLAY PROCESSQPRONAMEQ?

更改属?
ALTER QMGR DESCRQ?#8216;NEW DESCRIPTION’Q?
ALTER QLOCALQQNAMEQ?PUTQDISABLEDQ?
ALTER QALIASQQNAMEQ?TARGQQTARGQNAMEQ?

删除队列
DELETE QLOCALQQNAMEQ?
DELETE QREMOTEQQRNAMEQ?

清除队列中的所有消?
CLEAR QLOCALQQNAMEQ?

以下是一些高U配|的命o(h):

amqmcert                  配置SSL证书

amqmdain                配置windows上的MQ服务

crtmqcvx                    转换数据

dmpmqaut                转储对象权限理

dmpmqlog                转储日志理

dspmq                         昄队列理?/p>

dspmqaut                  昄打开对象的权?/p>

dmpmqcap               昄处理E序定w和处理程序数

dspmqcsv                 昄命o(h)服务器状?/p>

dspmqfls                   昄文g?/p>

dspmqtrc                   跟踪MQ输出(HP-UNIX LINUX Solaris)

dspmqrtn                   昄事务的详l信?/p>

endmqcsv                 停止队列理器上的命令服务器

strmqcsv                    启动队列理器上的命令服务器

endmqtrc                   停止跟踪

rcdmqimg                  向日志写对象的映?/p>

rcmqobj                      Ҏ(gu)日志中的映像重新创徏一个对?/p>

rsvmqtrn                     提交或逆序恢复事务

 




john 2007-12-26 17:26 发表评论
]]>
Linuxpȝ环境下的Socket~程详细解析http://www.aygfsteel.com/john_yu/archive/2007/07/23/131945.htmljohnjohnMon, 23 Jul 2007 14:45:00 GMThttp://www.aygfsteel.com/john_yu/archive/2007/07/23/131945.htmlhttp://www.aygfsteel.com/john_yu/comments/131945.htmlhttp://www.aygfsteel.com/john_yu/archive/2007/07/23/131945.html#Feedback0http://www.aygfsteel.com/john_yu/comments/commentRss/131945.htmlhttp://www.aygfsteel.com/john_yu/services/trackbacks/131945.htmlLinuxpȝ环境下的Socket~程详细解析

什么是Socket

  Socket接口是TCP/IP|络的APIQSocket接口定义了许多函数或例程Q程序员可以用它们来开发TCP/IP|络上的应用E序。要学Internet上的TCP/IP|络~程Q必ȝ解Socket接口?

  Socket接口设计者最先是接口放在Unix操作pȝ里面的。如果了解Unixpȝ的输入和输出的话Q就很容易了解Socket了。网l的Socket数据传输是一U特D的I/OQSocket也是一U文件描q符。Socket也具有一个类g打开文g的函数调用Socket()Q该函数q回一个整型的Socket描述W,随后的连接徏立、数据传输等操作都是通过该Socket实现的。常用的Socketcd有两U:(x)式SocketQSOCK_STREAMQ和数据报式SocketQSOCK_DGRAMQ。流式是一U面向连接的SocketQ针对于面向q接的TCP服务应用Q数据报式Socket是一U无q接的SocketQ对应于无连接的UDP服务应用?

  Socket建立

  Z建立SocketQ程序可以调用Socket函数Q该函数q回一个类g文g描述W的句柄。socket函数原型为:(x)

  int socket(int domain, int type, int protocol);

  domain指明所使用的协议族Q通常为PF_INETQ表CZ联网协议族(TCP/IP协议族)Qtype参数指定socket的类型:(x)SOCK_STREAM 或SOCK_DGRAMQSocket接口q定义了原始SocketQSOCK_RAWQ,允许E序使用低层协议Qprotocol通常赋?0"。Socket()调用q回一个整型socket描述W,你可以在后面的调用用它?/span>

  Socket描述W是一个指向内部数据结构的指针Q它指向描述W表入口。调用Socket函数Ӟsocket执行体将建立一个SocketQ实际上"建立一个Socket"意味着Z个Socket数据l构分配存储I间。Socket执行体ؓ(f)你管理描q符表?/span>

  两个|络E序之间的一个网l连接包括五U信息:(x)通信协议、本地协议地址、本C机端口、远端主机地址和远端协议端口。Socket数据l构中包含这五种信息?

  Socket配置

  通过socket调用q回一个socket描述W后Q在使用socketq行|络传输以前Q必配|该socket。面向连接的socket客户端通过调用Connect函数在socket数据l构中保存本地和q端信息。无q接socket的客L(fng)和服务端以及(qing)面向q接socket的服务端通过调用bind函数来配|本C息?
Bind函数socket与本Z的一个端口相兌Q随后你可以在该端口监听服务请求。Bind函数原型为:(x)

  

int bind(int sockfd,struct sockaddr *my_addr, int addrlen); 
  Sockfd是调用socket函数q回的socket描述W? my_addr是一个指向包含有本机IP地址?qing)端口号{信息的sockaddrcd的指针; addrlen常被讄为sizeof(struct sockaddr)?
  struct sockaddrl构cd是用来保存socket信息的:(x)
  struct sockaddr {
   unsigned short sa_family; /* 地址族, AF_xxx */
char sa_data[14]; /* 14 字节的协议地址 */
};
  sa_family一般ؓ(f)AF_INETQ代表InternetQTCP/IPQ地址族;sa_data
则包含该socket的IP地址和端口号?
  另外q有一U结构类型:(x)
  struct sockaddr_in {
   short int sin_family; /* 地址?*/
   unsigned short int sin_port; /* 端口?*/
   struct in_addr sin_addr; /* IP地址 */
   unsigned char sin_zero[8]; /* 填充0 以保持与struct sockaddr同样大小 */
  };

 

  q个l构更方便用。sin_zero用来sockaddr_inl构填充Cstruct sockaddr同样的长度,可以用bzero()或memset()函数其|ؓ(f)零。指向sockaddr_in 的指针和指向sockaddr的指针可以相互{换,q意味着如果一个函数所需参数cd是sockaddrӞ你可以在函数调用的时候将一个指向sockaddr_in的指针{换ؓ(f)指向sockaddr的指针;或者相反?

  使用bind函数Ӟ可以用下面的赋值实现自动获得本机IP地址和随取一个没有被占用的端口号Q?

  my_addr.sin_port = 0; /* pȝ随机选择一个未被用的端口?*/
  my_addr.sin_addr.s_addr = INADDR_ANY; /* 填入本机IP地址 */
通过my_addr.sin_port|ؓ(f)0Q函C(x)自动Z选择一个未占用的端口来使用。同P通过my_addr.sin_addr.s_addr|ؓ(f)INADDR_ANYQ系l会(x)自动填入本机IP地址?/span>

  注意在用bind函数是需要将sin_port和sin_addr转换成ؓ(f)|络字节优先序Q而sin_addr则不需要{换?/span>

  计算机数据存储有两种字节优先序Q高位字节优先和低位字节优先。Internet上数据以高位字节优先序在网l上传输Q所以对于在内部是以低位字节优先方式存储数据的机器,在Internet上传输数据时需要进行{换,否则׃(x)出现数据不一致?/span>

  下面是几个字节顺序{换函敎ͼ(x)

·htonl()Q把32位gL字节序{换成|络字节?
·htons()Q把16位gL字节序{换成|络字节?
·ntohl()Q把32位g|络字节序{换成L字节?
·ntohs()Q把16位g|络字节序{换成L字节?

 

  Bind()函数在成功被调用时返?Q出现错误时q回"-1"q将errno|ؓ(f)相应的错误号。需要注意的是,在调用bind函数时一般不要将端口L(fng)为小?024的|因ؓ(f)1?024是保留端口号Q你可以选择大于1024中的M一个没有被占用的端口号?

q接建立

 

  面向q接的客L(fng)序用Connect函数来配|socketq与q端服务器徏立一个TCPq接Q其函数原型为:(x)

  int connect(int sockfd, struct sockaddr *serv_addr,int addrlen);
Sockfd是socket函数q回的socket描述W;serv_addr是包含远端主机IP地址和端口号的指针;addrlen是远端地质结构的长度。Connect函数在出现错误时q回-1Qƈ且设|errno为相应的错误码。进行客L(fng)E序设计无须调用bind()Q因U情况下只需知道目的机器的IP地址Q而客户通过哪个端口与服务器建立q接q不需要关心,socket执行体ؓ(f)你的E序自动选择一个未被占用的端口Qƈ通知你的E序数据什么时候到打断口?/span>

  Connect函数启动和远端主机的直接q接。只有面向连接的客户E序使用socket时才需要将此socket与远端主机相q。无q接协议从不建立直接q接。面向连接的服务器也从不启动一个连接,它只是被动的在协议端口监听客L(fng)h?

  Listen函数使socket处于被动的监听模式,qؓ(f)该socket建立一个输入数据队列,到辄服务h保存在此队列中,直到E序处理它们?/span>

  int listen(int sockfdQ?int backlog);

  Sockfd是Socketpȝ调用q回的socket 描述W;backlog指定在请求队列中允许的最大请求数Q进入的q接h在队列中等待accept()它们Q参考下文)。Backlog寚w列中{待服务的请求的数目q行了限Ӟ大多数系l缺省gؓ(f)20。如果一个服务请求到来时Q输入队列已满,该socket拒l连接请求,客户收C个出错信息?/span>

  当出现错误时listen函数q回-1Qƈ|相应的errno错误码?/span>

  accept()函数让服务器接收客户的连接请求。在建立好输入队列后Q服务器p用accept函数Q然后睡眠ƈ{待客户的连接请求?/span>

  int accept(int sockfd, void *addr, int *addrlen);

  sockfd是被监听的socket描述W,addr通常是一个指向sockaddr_in变量的指针,该变量用来存放提接请求服务的L的信息(某台L从某个端口发hQ;addrten通常Z个指向gؓ(f)sizeof(struct sockaddr_in)的整型指针变量。出现错误时accept函数q回-1q置相应的errno倹{?/span>

  首先Q当accept函数监视的socket收到q接hӞsocket执行体将建立一个新的socketQ执行体这个新socket和请求连接进E的地址联系hQ收到服务请求的初始socket仍可以l在以前?socket上监听,同时可以在新的socket描述W上q行数据传输操作?

  数据传输

  Send()和recv()q两个函数用于面向连接的socket上进行数据传输?

  Send()函数原型为:(x)

  int send(int sockfd, const void *msg, int len, int flags);
Sockfd是你想用来传输数据的socket描述W;msg是一个指向要发送数据的指针QLen是以字节为单位的数据的长度;flags一般情况下|ؓ(f)0Q关于该参数的用法可参照man手册Q?

  Send()函数q回实际上发送出的字节数Q可能会(x)于你希望发送的数据。在E序中应该将send()的返回gƲ发送的字节数进行比较。当send()q回glen不匹配时Q应该对q种情况q行处理?
char *msg = "Hello!";
int len, bytes_sent;
……
len = strlen(msg);
bytes_sent = send(sockfd, msg,len,0);
……
  recv()函数原型为:(x)

  int recv(int sockfd,void *buf,int len,unsigned int flags);

  Sockfd是接受数据的socket描述W;buf 是存放接收数据的~冲区;len是缓冲的长度。Flags也被|ؓ(f)0。Recv()q回实际上接收的字节敎ͼ当出现错误时Q返?1q置相应的errno倹{?

  Sendto()和recvfrom()用于在无q接的数据报socket方式下进行数据传输。由于本地socketq没有与q端机器建立q接Q所以在发送数据时应指明目的地址?
  Sendto()函数原型为:(x)
  int sendto(int sockfd, const void *msg,int len,unsigned int flags,const struct sockaddr *to, int tolen);

  该函数比send()函数多了两个参数Qto表示目地机的IP地址和端口号信息Q而tolen常常被赋gؓ(f)sizeof (struct sockaddr)。Sendto 函数也返回实际发送的数据字节长度或在出现发送错误时q回-1?

  Recvfrom()函数原型为:(x)

  int recvfrom(int sockfd,void *buf,int len,unsigned int flags,struct sockaddr *from,int *fromlen);

  from是一个struct sockaddrcd的变量,该变量保存源机的IP地址?qing)端口号。fromlen常置为sizeof (struct sockaddr)。当recvfrom()q回Ӟfromlen包含实际存入from中的数据字节数。Recvfrom()函数q回接收到的字节数或当出现错误时q回

  1Qƈ|相应的errno?

  如果你对数据报socket调用了connect()函数Ӟ你也可以利用send()和recv()q行数据传输Q但该socket仍然是数据报socketQƈ且利用传输层的UDP服务。但在发送或接收数据报时Q内怼(x)自动Z加上目地和源地址信息?

  l束传输

  当所有的数据操作l束以后Q你可以调用close()函数来释放该socketQ从而停止在该socket上的M数据操作Q?

  close(sockfd);

  你也可以调用shutdown()函数来关闭该socket。该函数允许你只停止在某个方向上的数据传输,而一个方向上的数据传输l进行。如你可以关闭某socket的写操作而允许l在该socket上接受数据,直至d所有数据?

  int shutdown(int sockfd,int how);

  Sockfd是需要关闭的socket的描q符。参?how允许为shutdown操作选择以下几种方式Q?
·0-------不允许l接收数?
·1-------不允许l发送数?
·2-------不允许l发送和接收数据Q?
·均ؓ(f)允许则调用close ()

  shutdown在操作成功时q回0Q在出现错误时返?1q置相应errno?/span>

 面向q接的Socket实例

 

  代码实例中的服务器通过socketq接向客L(fng)发送字W串"Hello, you are connected!"。只要在服务器上q行该服务器软gQ在客户端运行客戯YӞ客户端就?x)收到该字符丌Ӏ?

  该服务器软g代码如下Q?

#include  
#include
#include
#include
#include
#include
#include
#include
#define SERVPORT 3333 /*服务器监听端口号 */
#define BACKLOG 10 /* 最大同时连接请求数 */
main()
{
int sockfd,client_fd; /*sock_fdQ监听socketQclient_fdQ数据传输socket */
 struct sockaddr_in my_addr; /* 本机地址信息 */
 struct sockaddr_in remote_addr; /* 客户端地址信息 */
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
  perror("socket创徏出错Q?); exit(1);
}
my_addr.sin_family=AF_INET;
 my_addr.sin_port=htons(SERVPORT);
 my_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(my_addr.sin_zero),8);
 if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) \
   == -1) {
perror("bind出错Q?);
exit(1);
}
 if (listen(sockfd, BACKLOG) == -1) {
perror("listen出错Q?);
exit(1);
}
while(1) {
  sin_size = sizeof(struct sockaddr_in);
  if ((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr, \
  &sin_size)) == -1) {
perror("accept出错");
continue;
}
  printf("received a connection from %s\n", inet_ntoa(remote_addr.sin_addr));
  if (!fork()) { /* 子进E代码段 */
   if (send(client_fd, "Hello, you are connected!\n", 26, 0) == -1)
   perror("send出错Q?);
close(client_fd);
exit(0);
}
  close(client_fd);
  }
 }
}

 

  服务器的工作程是这L(fng)Q首先调用socket函数创徏一个SocketQ然后调用bind函数其与本机地址以及(qing)一个本地端口号l定Q然后调用listen在相应的socket上监听,当accpet接收C个连接服务请求时Q将生成一个新的socket。服务器昄该客h的IP地址Qƈ通过新的socket向客L(fng)发送字W串"HelloQyou are connected!"。最后关闭该socket?/span>

  代码实例中的fork()函数生成一个子q程来处理数据传输部分,fork()语句对于子进E返回的gؓ(f)0。所以包含fork函数的if语句是子q程代码部分Q它与if语句后面的父q程代码部分是ƈ发执行的?

  客户端程序代码如下:(x)

#include 
#include
#include
#include
#include
#include
#include
#include
#define SERVPORT 3333
#define MAXDATASIZE 100 /*每次最大数据传输量 */
main(int argc, char *argv[]){
 int sockfd, recvbytes;
 char buf[MAXDATASIZE];
 struct hostent *host;
 struct sockaddr_in serv_addr;
 if (argc < 2) {
fprintf(stderr,"Please enter the server's hostname!\n");
exit(1);
}
 if((host=gethostbyname(argv[1]))==NULL) {
herror("gethostbyname出错Q?);
exit(1);
}
 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
perror("socket创徏出错Q?);
exit(1);
}
 serv_addr.sin_family=AF_INET;
 serv_addr.sin_port=htons(SERVPORT);
 serv_addr.sin_addr = *((struct in_addr *)host->h_addr);
 bzero(&(serv_addr.sin_zero),8);
 if (connect(sockfd, (struct sockaddr *)&serv_addr, \
   sizeof(struct sockaddr)) == -1) {
perror("connect出错Q?);
exit(1);
}
 if ((recvbytes=recv(sockfd, buf, MAXDATASIZE, 0)) ==-1) {
perror("recv出错Q?);
exit(1);
}
 buf[recvbytes] = '\0';
 printf("Received: %s",buf);
 close(sockfd);
}
客户端程序首先通过服务器域名获得服务器的IP地址Q然后创Z个socketQ调用connect函数与服务器建立q接Q连接成功之后接收从服务器发送过来的数据Q最后关闭socket?

  函数gethostbyname()是完成域名{换的。由于IP地址难以记忆和读写,所以ؓ(f)了方便,Z常常用域名来表示LQ这需要进行域名和IP地址的{换。函数原型ؓ(f)Q?/span>


  struct hostent *gethostbyname(const char *name); 
  函数q回为hosten的结构类型,它的定义如下Q?
  struct hostent {
  char *h_name; /* L的官方域?*/
   char **h_aliases; /* 一个以NULLl尾的主机别名数l?*/
   int h_addrtype; /* q回的地址cdQ在Internet环境下ؓ(f)AF-INET */
  int h_length; /* 地址的字节长?*/
   char **h_addr_list; /* 一个以0l尾的数l,包含该主机的所有地址*/
  };
  #define h_addr h_addr_list[0] /*在h-addr-list中的W一个地址*/

 

  ?gethostname()调用成功Ӟq回指向struct hosten的指针,当调用失败时q回-1。当调用gethostbynameӞ你不能用perror()函数来输出错误信息,而应该用herror()函数来输出?

  无连接的客户/服务器程序的在原理上和连接的客户/服务器是一L(fng)Q两者的区别在于无连接的客户/服务器中的客户一般不需要徏立连接,而且在发送接收数据时Q需要指定远端机的地址?

  d和非d

  d函数在完成其指定的Q务以前不允许E序调用另一个函数。例如,E序执行一个读数据的函数调用时Q在此函数完成读操作以前不?x)执行下一E序语句。当服务器运行到accept语句Ӟ而没有客戯接服务请求到来,服务器就?x)停止在accept语句上等待连接服务请求的到来。这U情늧为阻塞(blockingQ。而非d操作则可以立卛_成。比如,如果你希望服务器仅仅注意(g)查是否有客户在等待连接,有就接受q接Q否则就l箋做其他事情,则可以通过Socket讄为非d方式来实现。非dsocket在没有客户在{待时就使accept调用立即q回?
  #include
  #include
  ……
sockfd = socket(AF_INET,SOCK_STREAM,0);
fcntl(sockfd,F_SETFL,O_NONBLOCK)Q?
……

  通过讄socket为非d方式Q可以实?轮询"若干Socket。当企图从一个没有数据等待处理的非阻塞Socketd数据Ӟ函数立卌回,q回gؓ(f)-1Qƈ|errnogؓ(f)EWOULDBLOCK。但是这U?轮询"?x)CPU处于忙等待方式,从而降低性能Q浪费系l资源。而调用select()?x)有效地解决q个问题Q它允许你把q程本n挂v来,而同时ɾpȝ内核监听所要求的一l文件描q符的Q何活动,只要认在Q何被监控的文件描q符上出现活动,select()调用返回指C文g描述W已准备好的信息Q从而实CE选出随机的变化,而不必由q程本n对输入进行测试而浪费CPU开销。Select函数原型?
int select(int numfds,fd_set *readfds,fd_set *writefdsQ?
fd_set *exceptfds,struct timeval *timeout);

  其中readfds、writefds、exceptfds分别是被select()监视的读、写和异常处理的文g描述W集合。如果你希望定是否可以从标准输入和某个socket描述W读取数据,你只需要将标准输入的文件描q符0和相应的sockdtfd加入到readfds集合中;numfds的值是需要检查的L(fng)最高的文g描述W加1Q这个例子中numfds的值应为sockfd+1Q当selectq回Ӟreadfds被修改Q指C某个文件描q符已经准备被读取,你可以通过FD_ISSSET()来测试。ؓ(f)了实现fd_set中对应的文g描述W的讄、复位和试Q它提供了一l宏Q?
  FD_ZERO(fd_set *set)----清除一个文件描q符集;
  FD_SET(int fd,fd_set *set)----一个文件描q符加入文g描述W集中;
  FD_CLR(int fd,fd_set *set)----一个文件描q符从文件描q符集中清除Q?
  FD_ISSET(int fd,fd_set *set)----试判断是否文件描q符被置位?
  Timeout参数是一个指向struct timevalcd的指针,它可以select()在等待timeout长时间后没有文g描述W准备好卌回。struct timeval数据l构为:(x)
  struct timeval {
   int tv_sec; /* seconds */
   int tv_usec; /* microseconds */ };

  POP3客户端实?

  下面的代码实例基于POP3的客户协议,与邮件服务器q接q取回指定用户帐L(fng)邮g。与邮g服务器交互的命o(h)存储在字W串数组POPMessage中,E序通过一个do-while循环依次发送这些命令?

#include 
#include
#include
#include
#include
#include
#include
#include
#define POP3SERVPORT 110
#define MAXDATASIZE 4096

 

main(int argc, char *argv[]){
int sockfd;
struct hostent *host;
struct sockaddr_in serv_addr;
char *POPMessage[]={
"USER userid\r\n",
"PASS password\r\n",
"STAT\r\n",
"LIST\r\n",
"RETR 1\r\n",
"DELE 1\r\n",
"QUIT\r\n",
NULL
};
int iLength;
int iMsg=0;
int iEnd=0;
char buf[MAXDATASIZE];

if((host=gethostbyname("your.server"))==NULL) {
perror("gethostbyname error");
exit(1);
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
perror("socket error");
exit(1);
}
serv_addr.sin_family=AF_INET;
serv_addr.sin_port=htons(POP3SERVPORT);
serv_addr.sin_addr = *((struct in_addr *)host->h_addr);
bzero(&(serv_addr.sin_zero),8);
if (connect(sockfd, (struct sockaddr *)&serv_addr,sizeof(struct sockaddr))==-1){
perror("connect error");
exit(1);
}

do {
send(sockfd,POPMessage[iMsg],strlen(POPMessage[iMsg]),0);
printf("have sent: %s",POPMessage[iMsg]);

iLength=recv(sockfd,buf+iEnd,sizeof(buf)-iEnd,0);
iEnd+=iLength;
buf[iEnd]='\0';
printf("received: %s,%d\n",buf,iMsg);

iMsg++;
} while (POPMessage[iMsg]);

close(sockfd);
}



john 2007-07-23 22:45 发表评论
]]>
վ֩ģ壺 | | | | | ʯɽ| | | ˮ| | | | ƽ| | μ| ͬ| | | ȷ| | | ˰| | | | | | | | ˫| Ƕ| ɽ| | | Ϊ| | ũ| ɽ| ˮ| | |