happy study
merry

Sunday, July 09, 2006

1.客户端
我们先从客户端开始,它用远端的机器名作为参数。它调用UNIX程序gethostbyname把该名字转化为远端主机的IP地址。下一步构造套接字接口所需的地址数据结构(sin)。注意这个数据结构表明我们将一直用套接字与因特网(AF_INET)连接。在这个例子中,我们用TCP端口号5432作为共知的服务器端口号;它恰好不是分配给其他因特网服务的端口号。建立连接的最后一步是调用socket和connect。一旦connect操作返回,建立起连接,客户程序将进入主循环,不断从标准输入读文本并通过套接字发送。
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#define SERVER_PORT 5432
#define MAX_LINE 256

int
main(int argc,char * argv[])
{
  FILE *fp;
struct hostent *hp;
struct sockaddr_in sin;
char *host;
char buf[MAX_LINE];
int s;
  int len;

  if(argc==2){
 host=argv[1];
}
  else {
    fprintf(stderr,”usage:simplex-talk host\n”);
    exit(1);
  }
/* 将主机名翻译成对等实体的IP地址 */
hp=gethostbyname(host);
if(!hp) {
 fprintf(stderr,”simplex-talk:unknown host:%s\n”,host);
 exit(1);
  }    

/* 建立地址数据结构 */
bzero((char *)&sin,sizeof(sin));
sin.sin_family=AF_INET;
bcopy(hp->h_addr,(char *)&sin.sin_addr,hp->h_length);
sin.sin_port=htons(SERVER_PORT);

/* 主动打开 */
if((s=socket(PF_INET,SOCK_STREAM,0))<0) {
    perror(“simplex-talk:socket”);
exit(1);
}
if(connect(s, (struct sockaddr *)&sin,sizeof(sin)) <0  ) {

perror(“simplex-talk:connect”);
close(s);
exit(1);
}

/* 主循环:获得并发送文本行 */
while(fgets(buf,sizeof(buf),stdin)){
buf[MAX_LINE-1]=’\0’;
len=strlen(buf)+1;
send(s,buf,len,0);
}
}
2.服务器
服务器的实现也很简单。首先,它填上自己的端口号(SERVER_PORT)构造地址数据结构。其次,它并不指明IP地址,从而使应用程序可以接受来自本地任一IP地址的连接。然后,服务器执行与被动打开有关的初始步骤:建立一个套接字,将它绑定到本地地址,然后设置允许同时连接的最大数。最后,主循环等待远端主机试图与之连接,当远端有一台主机试图与之连接时,它就接收并输出连接上送来的字符。
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#define SERVER_PORT 5432
#define MAX_PENDING 5
#define MAX_LINE 256

int main()
{
  struct sockaddr_in sin;
  char buf[MAX_LINE];
  int len;
int s,new_s;
 
/* 建立地址数据结构 */
bzero((char *)&sin,sizeof(sin));
sin.sin_family=AF_INET;
sin.sin_addr.s_addr=INADDR_ANY;
sin.sin_port=htons(SERVER_PORT);

/* 建立被动连接 */
if((s=socket(PF_INET,SOCK_STREAM,0))<0) {
perror(“simplex-talk:socket”);
exit(1);
}
if((bind(s,(struct sockaddr *)&sin,sizeof(sin)))<0) {
perror(“simplex-talk:bind”);
exit(1);
}
listen(s,MAX_PENDING);
 
/* 等待连接,然后接收并输出文本 */
while(1) {
  if((new_s=accept(s,(struct sockaddr *)&sin,&len))<0) {
    perror(“simplex-talk:accept”);
    exit(1);
}
while(len=recv(new_s,buf,sizeof(buf),0))
fputs(buf,stdout);
close(new_s);
}
}

posted @ 11:54 PM