蕙兰瑜伽简易入门,socket简易入门手册

socket简易入门手册 - 菜鸟学院 - 电脑教程网

socket简易入门手册

日期:2006-11-12   荐:
1、介绍
  当你进入UNIX的神秘世界后,立刻会发现越来越多的东西难以理解。对于大多数人来说,BSDsocket的概念就是其中一个。这是一个很短的教程来解释他们是什么、他们如何工作并给出一些简单的代码来解释如何使用他们。

2、类比(什么是socket?)
  socket是进行程序间通讯(IPC)的BSD方法。这意味着socket用来让一个进程和其他的进程互通信息,就象我们用电话来和其他的人交流一样。

  用电话来比喻是很恰当的,我们在后面将一直用电话这个概念来描叙socket。

3、装上你的新电话(怎样侦听?)
  一个人要能够收到别人打给他的电话,首先他要装上一门电话。同样,你必须先建立socket以侦听线路。这个过程包含几个步骤。首先,你要建立一个新的socket,就象先装上电话一样。socket()命令就完成这个工作。

  因为sockets有几种类型,你要注明你要建立什么类型的。你要做一个选择是socket的地址格式。如同电话有音频和脉冲两种形式一样, socket有两个最重要的选项是AF_UNIX和IAF_INET。AF_UNIX就象UNIX路径名一样识别sockets。这种形式对于在同一台机器上的IPC很有用。而AF_INET使用象192.9.200.10这样被点号隔开的四个十进制数字的地址格式。除了机器地址以外,还可以利用端口号来允许每台机器上的多个AF_INETsocket。我们这里将着重于AF_INET方式,因为他很有用并广泛使用。

  另外一个你必须提供的参数是socket的类型。两个重要的类型是SOCK_STREAM和SOCK_DGRAM。SOCK_STREAM表明数据象字符流一样通过socket。而SOCK_DGRAM则表明数据将是数据报(datagrams)的形式。我们将讲解 SOCK_STREAMsockets,他很常见并易于使用。

  在建立socket后,我们就要提供socket侦听的地址了。就象你还要个电话号码来接电话一样。bind()函数来处理这件事情。

  SOCK_STREAMsockets让连接请求形成一个队列。如果你忙于处理一个连接,别的连接请求将一直等待到该连接处理完毕。listen()函数用来设置最大不被拒绝的请求数(一般为5个)。一般最好不要使用listen()函数。

  下面的代码说明如何利用socket()、bind()和listen()函数建立连接并可以接受数据。

  /*codetoestablishasocket;[email protected]
  */

intestablish(unsignedshortportnum)
  {charmyname[MAXHOSTNAME+1];
  ints;
  strUCtsockaddr_insa;
  structhostent*hp;

memset(&sa,0,sizeof(structsockaddr_in));/*clearouraddress*/
  gethostname(myname,MAXHOSTNAME);/*whoarewe?*/
  hp=gethostbyname(myname) ;

/* get our address info */
   if (hp == NULL) /* we dont exist !? */
   return(-1);
   sa.sin_family= hp->h_addrtype; /* this is our host address */
   sa.sin_port= htons(portnum); /* this is our port number */
   if ((s= socket(AF_INET, SOCK_STREAM, 0)) /* obligatory includes */
  #include
  #include
  #include
  #include
  #include
  #include
  #include
  #include

#define PORTNUM 50000 /* random port number, we need something */

void fireman(void);
  void do_something(int);

main()
  { int s, t;

if ((s= establish(PORTNUM)) 0)
   ;
  }

/* this is the function that plays with the socket. it will be called
   * after getting a connection.
   */
  void do_something(int s)
  {
   /* do your thing with the socket here
   :
   :
   */
  }

  4、拨号 (如何调用 socket)
  现在你应该知道如何建立 socket 来接受调用了。那么如何调用呢?和电话一样,你要先有个电话。用 socket() 函数来完成这件事情,就象建立侦听的 socket 一样。

  在给 socket 地址后,你可以用 connect() 函数来连接侦听的 socket 了。下面是一段代码。

  int call_socket(char *hostname, unsigned short portnum)
  { struct sockaddr_in sa;
   struct hostent *hp;
   int a, s;

if ((hp= gethostbyname(hostname)) == NULL) { /* do we know the hosts */
   errno= ECONNREFUSED; /* address? */
   return(-1); /* no */
   }

memset(&sa,0,sizeof(sa));
   memcpy((char *)&sa.sin_addr,hp->h_addr,hp->h_length); /* set address */

[1] [2]  

   sa.sin_family= hp->h_addrtype;
   sa.sin_port= htons((u_short)portnum);

if ((s= socket(hp->h_addrtype,SOCK_STREAM,0)) 0) {
   bcount += br; /* increment byte counter */
   buf += br; /* move buffer ptr for next read */
   }
   else if (br < 0) /* signal an error to the caller */
   return(-1);
   }
   return(bcount);
  }

  相同的函数也可以写数据,留给我们的读者吧。

  5、谈话

  6、挂起(结束)
  和你通过电话和某人交谈后一样,你要在 socket 间关闭连接。一般 close() 函数用来关闭每边的 socket 连接。如果一边的已经关闭,而另外一边却在向他写数据,则返回一个错误代码。

  7、世界语(交流的语言很重要)
  现在你可以在机器间联络了,可是要小心你所说的话。许多机器有自己的方言,如 ASCII 和 EBCDIC。更常见的问题是字节顺序问题。除非你一直传输的都是文本,否则你一定要注意这个问题。幸运的是,人们找出了解决的办法。

  在很久以前,人们争论哪种顺序更“正确”。现在必要时有相应的函数来转换。其中有 htons()、ntohs()、htonl() 和 ntohl()。在传输一个整型数据前,先转换一下。

  i= htonl(i);
  write_data(s, &i, sizeof(i));

  在读数据后,再变回来。

  read_data(s, &i, sizeof(i));
  i= ntohl(i);

  如果你一直坚持这个习惯,你将比别人少出错的机会。

  8、未来在你的掌握了(下一步?)
  就用我们刚才讨论的东西,你就可以写自己的通讯程序了。和对待所有的新生事物一样, 最好还是看看别人已经做了些什么。这里有许多关于 BSD socket 的东西可以参考。

  请注意,例子中没有错误检查,这在“真实”的程序中是很重要的。你应该对此充分重视。

(出处:http://www.sheup.com)


 [1] [2] 


  请注意,例子中没有错误检查,这在“真实”的程序中是很重要的。你应该对此充分重视。

(出处:http://www.sheup.com)


 [1] [2] [3] 

标签: