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

DVD

开发平台:

Unix_Linux

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