network.cc,v
上传用户:aoeyumen
上传日期:2007-01-06
资源大小:3329k
文件大小:13k
源码类别:

DVD

开发平台:

Unix_Linux

  1. head     1.1;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @@;
  7. 1.1
  8. date     96.11.08.11.30.32;  author dejong;  state Exp;
  9. branches ;
  10. next     ;
  11. desc
  12. @Fixed bug in Tcp::recv at EOF return 0 (don't wait)
  13. @
  14. 1.1
  15. log
  16. @Initial revision
  17. @
  18. text
  19. @/*
  20.    File: network.cc
  21.    By: Alex Theo de Jong
  22.    Created: April 1996
  23.    Description:
  24.    This file contains all network functions to be used with the mpeg2player. This
  25.    is a temporary solution. The complete AtmSocket API should be used for this
  26.    in order to use configuration/testing facilities. Hopefully we can do that im
  27.    June/July 1996
  28. */
  29. #ifdef __GNUG__
  30. #pragma implementation
  31. #endif
  32. #include "athread.hh"
  33. #include <stdio.h>
  34. #include <stdlib.h>
  35. #include <String.h>
  36. #include <fstream.h>
  37. #include <sys/time.h>
  38. #include <sys/errno.h>
  39. #include <fcntl.h>
  40. #ifdef IRIX
  41. #include <bstring.h>
  42. #include <stropts.h>
  43. #include <poll.h>
  44. #endif
  45. #include "error.hh"
  46. #include "debug.hh"
  47. #include "util.hh"
  48. #include "network.hh"
  49. // Socket File
  50. SocketFile::SocketFile(const char* filen){
  51.   TRACER("SocketFile::SocketFile(const char* filen)");
  52.   filename=filen;
  53.   /*
  54.   file.open(filename.chars());
  55.   if (!file){
  56.     error("could not open file `" << filename << "' for reading");
  57.   }
  58.   */
  59.   if ((socketfd=open(filename.chars(), O_RDONLY | O_NDELAY))<=0){
  60.     error("could not open file `" << filename << "' for reading");
  61.   }
  62. }
  63. SocketFile::~SocketFile(){
  64.   TRACER("SocketFile::~SocketFile()");
  65.   /*
  66.   if (filename.length()){
  67.     file.close();
  68.   }
  69.   */
  70.   ::close(socketfd);
  71. }
  72. int SocketFile::recv(unsigned char* data, int size){
  73.   DEBUGGER("int SocketFile::recv(unsigned char* data, int size)");
  74.   bfr=data;
  75.   read_bytes=0;
  76.   do {
  77.     /*
  78.     if ((bytes=(file.read(data, size).gcount()))<=0)
  79.     */
  80.     if ((bytes=read(socketfd, data, size))<=0)
  81.       return bytes;
  82.     bfr+=bytes;
  83.     read_bytes+=bytes;
  84.   }
  85.   while (read_bytes<size);
  86.   return read_bytes;
  87. };
  88. int SocketFile::close(){
  89.   TRACER("int SocketFile::close()");
  90.   if (filename.length() && socketfd>0){
  91.     return ::close(socketfd);
  92.   }
  93.   return -1;
  94. }
  95. // Socket TCP
  96. SocketTcp::SocketTcp(unsigned int asap, unsigned int pdu_size){
  97.   TRACER("SocketTcp::SocketTcp(unsigned int asap, unsigned int pdu_size)");
  98.   sockaddr_in server_addr;
  99.   
  100.   if ((socketfd=::socket(AF_INET, SOCK_STREAM, IPPROTO_IP))<0){
  101.     error("can't open stream socket");
  102.     exit(1);
  103.   }
  104.   
  105. #if (defined(IRIX) || defined(IRIX_PTHREAD))
  106.   bzero(&server_addr, sizeof(server_addr));
  107. #else
  108.   memset((char*) &server_addr, 0, sizeof(server_addr));
  109. #endif
  110.   
  111. #ifdef SOLARIS
  112.   struct hostent* host=0;
  113.   // Try ATM
  114.   String name(getenv("HOSTNAME"));
  115.   name+="-atm";  // default extension for ATM
  116.   if (name.length()!=0 && (host=gethostbyname(name.chars()))==0){
  117.     // if no ATM, try regular HOSTNAME address
  118.     if ((host=gethostbyname(getenv("HOSTNAME")))==0){
  119.       error("could not get host by name");
  120.       athr_exit(0);
  121.     }
  122.   }
  123.   server_addr.sin_addr.s_addr =((struct in_addr *) host->h_addr_list[0])->s_addr;
  124. #endif
  125.   
  126.   server_addr.sin_family=AF_INET;
  127.   server_addr.sin_port=htons(asap);
  128.   while (1){
  129.     if (::bind(socketfd, (struct sockaddr*) &server_addr, sizeof(server_addr))<0){
  130.       ::close(socketfd);
  131.       error("could not bind local address");
  132.       exit(1);
  133.     }
  134.     else break;
  135.     asap++;
  136.   }
  137.   
  138.   int reuseaddr=1;
  139.   if (setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, (char*) &reuseaddr, sizeof(reuseaddr))<0){
  140.     error("can't set sender socket option (SO_REUSEADDR)"); exit(1);
  141.   }
  142.   
  143.   if (pdu_size){
  144.     unsigned int read_size=pdu_size;
  145.     if (setsockopt(socketfd,SOL_SOCKET,SO_SNDBUF,(char*)&read_size,sizeof(read_size))<0){
  146.       error("can't set socket option (SO_SNDBUF)"); exit(1);
  147.     }
  148.     if (setsockopt(socketfd,SOL_SOCKET,SO_RCVBUF,(char*)&read_size,sizeof(read_size))<0){
  149.       error("can't set socket option (SO_RCVBUF)"); exit(1);
  150.     }
  151.   }
  152.   
  153.   int alive=1;
  154.   if (setsockopt(socketfd,SOL_SOCKET,SO_KEEPALIVE,(char*)&alive,sizeof(alive))<0){
  155.     error("can't set socket option (SO_KEEPALIVE)"); exit(1);
  156.   }
  157.   int error=0, error_len=sizeof(error);
  158.   if (getsockopt(socketfd, SOL_SOCKET, SO_ERROR, (char*) &error, &error_len)<0){
  159.     error("can't get sender socket option (SO_ERROR)"); exit(1);
  160.   }
  161.   
  162.   if (::listen(socketfd, 1)<0){
  163.     error("could not listen to connection");
  164.     exit(0);
  165.   }
  166. }
  167. SocketTcp::~SocketTcp(){
  168.   TRACER("SocketTcp::~SocketTcp");
  169.   ::close(fd);
  170. }
  171. int SocketTcp::accept(){
  172.   DEBUGGER("int SocketTcp::accept()");
  173.   sockaddr_in client_addr;
  174.   
  175.   int client_len=sizeof(client_addr);
  176. #if (defined(IRIX) || defined(IRIX_PTHREAD))
  177.   bzero(&client_addr, sizeof(client_addr));
  178. #else
  179.   memset((char*) &client_addr, 0, sizeof(client_addr));
  180. #endif
  181.   
  182.   if ((fd=::accept(socketfd, (struct sockaddr*) &client_addr, &client_len))<=0){
  183.     error("could not accept connection (" << itoa(errno) << ")");
  184.     athr_exit(0);
  185.   }
  186.   ::close(socketfd);
  187.   message("received connection on TCP!");
  188.   
  189.   return fd;
  190. }
  191. int SocketTcp::recv(unsigned char* data, int size){
  192.   DEBUGGER("int SocketTcp::recv(unsigned char* data, int size)");
  193.   bfr=data;
  194.   read_bytes=0;
  195.   do {
  196.     if ((bytes=::read(fd, bfr, size-read_bytes))<=0)
  197.       return bytes;
  198.     bfr+=bytes;
  199.     read_bytes+=bytes;
  200.   }
  201.   while (read_bytes<size);
  202. #ifdef DEEPDEBUG
  203.   static int count=0;
  204.   unsigned int test=((data[0]<<24) | (data[1] << 16) | (data[2]<<8) | data[3]);  printf("First 4 bytes=%xn", test);
  205.   test=((data[188]<<24) | (data[189] << 16) | (data[190]<<8) | data[191]); 
  206.   printf("First 4 bytes=%xn", test);
  207.   if (count++==10) exit(0);
  208. #endif
  209.   return read_bytes;
  210. };
  211. int SocketTcp::close(){
  212.   int err=::close(fd);
  213.   TRACER("int SocketTcp::close()");
  214.   return err;
  215. }
  216. // Socket UDP
  217. SocketUdp::SocketUdp(unsigned int asap, unsigned int pdu_size){
  218.   TRACER("SocketUdp::SocketUdp()");
  219.   sockaddr_in server_addr;
  220.   
  221.   if ((socketfd=::socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))<0){
  222.     error("can't open dgram socket");
  223.     exit(1);
  224.   }
  225.   
  226. #if (defined(IRIX) || defined(IRIX_PTHREAD))
  227.   bzero(&server_addr, sizeof(server_addr));
  228. #else
  229.   memset((char*) &server_addr, 0, sizeof(server_addr));
  230. #endif
  231.   
  232. #ifdef SOLARIS
  233.   struct hostent* host=0;
  234.   //  if (option==1){
  235.   if ((host=gethostbyname(getenv("HOSTNAME")))==0){
  236.     error("could not get host by name");
  237.     athr_exit(0);
  238.   }
  239.   /*
  240.   else {
  241.     String name(getenv("HOSTNAME"));
  242.     name+="-atm";  // default extension for ATM
  243.     if (name.length()!=0 && (host=gethostbyname(name.chars()))==0){
  244.       error("could not get host by name");
  245.       athr_exit(0);
  246.     }
  247.   }
  248.   */
  249.   server_addr.sin_addr.s_addr =((struct in_addr *) host->h_addr_list[0])->s_addr;
  250. #endif
  251.  
  252.   server_addr.sin_family=AF_INET;
  253.   server_addr.sin_port=htons(asap);
  254.   while (1){
  255.     if (::bind(socketfd, (struct sockaddr*) &server_addr, sizeof(server_addr))<0){
  256.       ::close(socketfd);
  257.       error("could not bind local address");
  258.       exit(1);
  259.     }
  260.     else break;
  261.     asap++;
  262.   }
  263.   
  264.   int reuseaddr=1;
  265.   if (setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, (char*) &reuseaddr, sizeof(reuseaddr))<0){
  266.     error("can't set sender socket option (SO_REUSEADDR)"); exit(1);
  267.   }
  268.  
  269.   if (pdu_size){
  270.     unsigned int read_size=pdu_size;
  271.     if (setsockopt(socketfd,SOL_SOCKET,SO_SNDBUF,(char*)&read_size,sizeof(read_size))<0){
  272.       error("can't set socket option (SO_SNDBUF)"); exit(1);
  273.     }
  274.     if (setsockopt(socketfd,SOL_SOCKET,SO_RCVBUF,(char*)&read_size,sizeof(read_size))<0){
  275.       error("can't set socket option (SO_RCVBUF)"); exit(1);
  276.     }
  277.   }
  278.   
  279.   int alive=1;
  280.   if (setsockopt(socketfd,SOL_SOCKET,SO_KEEPALIVE,(char*)&alive,sizeof(alive))<0){
  281.     error("can't set socket option (SO_KEEPALIVE)"); exit(1);
  282.   }
  283.   int error=0, error_len=sizeof(error);
  284.   if (getsockopt(socketfd, SOL_SOCKET, SO_ERROR, (char*) &error, &error_len)<0){
  285.     error("can't get sender socket option (SO_ERROR)"); exit(1);
  286.   }
  287.  
  288.   pcli_addr=(sockaddr*) &cli_addr;
  289.   cli_len=sizeof(cli_addr);
  290. }
  291. SocketUdp::~SocketUdp(){
  292.   TRACER("SocketUdp::~SocketUdp");
  293.   ::close(fd);
  294. }
  295. int SocketUdp::accept(){
  296.   TRACER("int SocketUdp::accept()");
  297.   fd=socketfd;
  298.   message("received connection on UDP!");
  299.   return fd;
  300. }
  301. int SocketUdp::recv(unsigned char* data, int size){
  302.   DEBUGGER("int SocketUdp::recv(unsigned char* data, int size)");
  303.   bfr=data;
  304.   read_bytes=0;
  305.   do {
  306.     if ((bytes=::recvfrom(fd, (char*) bfr, size-read_bytes, 0, pcli_addr, &cli_len))==size)
  307.       return bytes;
  308.     bfr+=bytes;
  309.     read_bytes+=bytes;
  310.   } 
  311.   while (read_bytes<size);
  312.   return read_bytes;
  313. }
  314. int SocketUdp::close(){
  315.   int err=::close(fd);
  316.   TRACER("int SocketUdp::close()");
  317.   return err;
  318. }
  319. #ifdef FORE_ATM
  320. // Socket ATM SPANS
  321. SocketAtmSpans::SocketAtmSpans(unsigned int sap) : asap(sap) {
  322.   TRACER("SocketAtmSpans::SocketAtmSpans(unsigned int sap)");
  323.   Atm_info info;
  324.   aal_type=aal_type_5;
  325.   dataflow=duplex;
  326.   
  327.   if ((socketfd=atm_open(ATMDEVICE, O_RDWR, &info))<0){
  328.     atm_error("atm_open : ");
  329.     exit(1);
  330.   }
  331.   
  332.   int queue_size=1;
  333.   if (atm_bind(socketfd, asap, &asap, queue_size)<0){
  334.     atm_error("atm_bind");
  335.     exit(1);
  336.   }
  337. }
  338. SocketAtmSpans::~SocketAtmSpans(){
  339.   TRACER("SocketAtmSpans::~SocketAtmSpans()");
  340.   ::atm_close(fd);
  341. }
  342. int SocketAtmSpans::accept(){
  343.   TRACER("int SocketAtmSpans::accept()");
  344.   Atm_qos qos_server;
  345.   int conn_id(0);
  346.   
  347.   if (atm_listen(socketfd, &conn_id, &atm_endpoint, &qos_server, &aal_type) < 0){
  348.     atm_error("atm_listen");
  349.     exit(1);
  350.   }
  351.   qos.peak_bandwidth.target  = qos_server.peak_bandwidth.target; 
  352.   qos.peak_bandwidth.minimum = qos_server.peak_bandwidth.minimum;
  353.   qos.mean_bandwidth.target  = qos_server.mean_bandwidth.target;
  354.   qos.mean_bandwidth.minimum = qos_server.mean_bandwidth.minimum;
  355.   qos.mean_burst.target      = qos_server.mean_burst.target;
  356.   qos.mean_burst.minimum     = qos_server.mean_burst.minimum;
  357.   
  358.   if (atm_accept(socketfd, socketfd, conn_id, &qos, dataflow) < 0) {
  359.     atm_error("atm_accept");
  360.     exit(1);
  361.   }
  362.   fd=socketfd;
  363.   message("received connection on ATM SPANS!");
  364.   return fd;
  365. }
  366. int SocketAtmSpans::recv(unsigned char* data, int size){
  367.   DEBUGGER("int SocketAtmSpans::recv(unsigned char* data, int size)");
  368.   bfr=data;
  369.   read_bytes=0;
  370.   do {
  371.     if ((bytes=::atm_recv(fd, (caddr_t) bfr, size-read_bytes))<=0)
  372.       // ATM returns -1 when connection is terminated
  373.       return (bytes==-1 || bytes==0) ? 0 : bytes;
  374.     bfr+=bytes;
  375.     read_bytes+=bytes;
  376.   }
  377.   while (read_bytes<size);
  378.   return read_bytes;
  379. }
  380. int SocketAtmSpans::close(){
  381.   int err=::atm_close(fd);
  382.   TRACER("int SocketAtmSpans::close()");
  383.   return err;
  384. }
  385. // class ATM PVC
  386. SocketAtmPvc::SocketAtmPvc(unsigned int vci, unsigned int vpi){
  387.   TRACER("SocketAtmPvc::SocketAtmPvc(unsigned int vci, unsigned int vpi)");
  388.   Atm_info info;
  389.   Atm_conn_resource  qos;
  390.   aal_type=aal_type_5;
  391.   if ((socketfd=atm_open(ATMDEVICE, O_RDWR, &info))<0){
  392.     atm_error("atm_open: ");
  393.     exit(1);
  394.   }
  395.   /*
  396.   if (info.mtu < pdu_size){
  397.     error("sdu size to big for maximum ATM mtu");
  398.     exit(1);
  399.   }
  400.   */
  401.   qos.peak_bandwidth =  50000;  // set some dummy values
  402.   qos.mean_bandwidth =  500000;
  403.   vpvc= (vpi  & 0x00000FFF) << 16;
  404.   vpvc+=(vci & 0x0000FFFF);
  405.   if (atm_bind_pvc(socketfd, vpvc, aal_type, &qos)!=0){
  406.     atm_error("atm_bind_pvc");
  407.     exit(1);
  408.   }
  409. }
  410. SocketAtmPvc::~SocketAtmPvc(){
  411.   TRACER("SocketAtmPvc::~SocketAtmPvc()");
  412.   ::atm_close(fd);
  413. }
  414. int SocketAtmPvc::accept(){
  415.   TRACER("int SocketAtmPvc::accept()");
  416.   fd=socketfd;  // ready to receive data
  417.   message("received connection on ATM PVC!");
  418.   return fd;
  419. }
  420. int SocketAtmPvc::recv(unsigned char* data, int size){
  421.   DEBUGGER("int SocketAtmPvc::recv(unsigned char* data, int size)");
  422.   bfr=data;
  423.   read_bytes=0;
  424.   do {
  425.     if ((bytes=::atm_recvfrom(fd, (caddr_t) bfr, size-read_bytes, &vpvc))<=1){
  426.       if (bytes==1) return 0; // eof   EOF protocol if using a PVC
  427.       return bytes;
  428.     }
  429.     bfr+=bytes;
  430.     read_bytes+=bytes;
  431.   }
  432.   while (read_bytes<size);
  433.   return read_bytes;
  434. }
  435.  
  436. int SocketAtmPvc::close(){
  437.   int err=::atm_close(fd);
  438.   TRACER("int SocketAtmPvc::close()");
  439.   return err;
  440. }
  441. #endif // FORE_ATM
  442. // SocketMulti waits at several ports and accepts the one first activated
  443. SocketMulti::SocketMulti(unsigned int asap, int pdu_size, unsigned int vci, unsigned int vpi){
  444.   TRACER("SocketMulti::SocketMulti(unsigned int asap, int pdu_size, vci, int vpi)");
  445.   sockets=new Socket*[SOCKETMULTI_MAX];
  446.   count=0;
  447.   sockets[count++]=new SocketTcp(asap, pdu_size);
  448.   sockets[count++]=new SocketUdp(asap, pdu_size);
  449. #ifdef FORE_ATM
  450.   // test to find ATM board
  451.   Atm_info info;
  452.   int dummy;
  453.   if ((dummy=atm_open(ATMDEVICE, O_RDWR, &info))>0){
  454.     atm_close(dummy);
  455.     // found an ATM board; thus include these while wating for connection
  456.     sockets[count++]=new SocketAtmSpans(asap);
  457.     sockets[count++]=new SocketAtmPvc(vci, vpi);
  458.   }
  459.   sockets[count]=0;
  460. #endif 
  461. }
  462. SocketMulti::SocketMulti(const char* name){ 
  463.   TRACER("SocketMulti::SocketMulti(const char* name)");
  464.   
  465.   sockets=0;
  466.   socket=new SocketFile(name);
  467.   count=1;
  468. }
  469. SocketMulti::~SocketMulti(){
  470.   if (sockets){
  471.     for (int i=0; sockets[i]!=0; i++) 
  472.       delete sockets[i];
  473.     delete[] sockets;
  474.   }
  475.   else delete socket;
  476. }
  477. int SocketMulti::accept(){
  478.   TRACER("int SocketMulti::accept()");
  479.   if (sockets==0) return 0;
  480.   pollfd fds[SOCKETMULTI_MAX];
  481.   for (int i=0; i<count; i++){
  482.     fds[i].fd=sockets[i]->socketfd;
  483.     fds[i].events= POLLRDNORM | POLLPRI; //  POLLIN | POLLRDBAND | );
  484.   }
  485.   message("waiting for connection ... ");
  486.   if (poll(fds, count, -1)<0){
  487.     error("could not call poll");
  488.     exit(1);
  489.   }
  490.   for (int j=0; j<count; j++){
  491.     if (fds[j].revents>0){
  492.       return (socket=sockets[j])->accept();
  493.     }
  494.   }
  495.   error("failed to find event after poll");
  496.   return -1;
  497. }
  498. @