head 1.1; branch ; access ; symbols ; locks ; strict; comment @@; 1.1 date 96.11.08.11.30.32; author dejong; state Exp; branches ; next ; desc @Fixed bug in Tcp::recv at EOF return 0 (don't wait) @ 1.1 log @Initial revision @ text @/* File: network.cc By: Alex Theo de Jong Created: April 1996 Description: This file contains all network functions to be used with the mpeg2player. This is a temporary solution. The complete AtmSocket API should be used for this in order to use configuration/testing facilities. Hopefully we can do that im June/July 1996 */ #ifdef __GNUG__ #pragma implementation #endif #include "athread.hh" #include #include #include #include #include #include #include #ifdef IRIX #include #include #include #endif #include "error.hh" #include "debug.hh" #include "util.hh" #include "network.hh" // Socket File SocketFile::SocketFile(const char* filen){ TRACER("SocketFile::SocketFile(const char* filen)"); filename=filen; /* file.open(filename.chars()); if (!file){ error("could not open file `" << filename << "' for reading"); } */ if ((socketfd=open(filename.chars(), O_RDONLY | O_NDELAY))<=0){ error("could not open file `" << filename << "' for reading"); } } SocketFile::~SocketFile(){ TRACER("SocketFile::~SocketFile()"); /* if (filename.length()){ file.close(); } */ ::close(socketfd); } int SocketFile::recv(unsigned char* data, int size){ DEBUGGER("int SocketFile::recv(unsigned char* data, int size)"); bfr=data; read_bytes=0; do { /* if ((bytes=(file.read(data, size).gcount()))<=0) */ if ((bytes=read(socketfd, data, size))<=0) return bytes; bfr+=bytes; read_bytes+=bytes; } while (read_bytes0){ return ::close(socketfd); } return -1; } // Socket TCP SocketTcp::SocketTcp(unsigned int asap, unsigned int pdu_size){ TRACER("SocketTcp::SocketTcp(unsigned int asap, unsigned int pdu_size)"); sockaddr_in server_addr; if ((socketfd=::socket(AF_INET, SOCK_STREAM, IPPROTO_IP))<0){ error("can't open stream socket"); exit(1); } #if (defined(IRIX) || defined(IRIX_PTHREAD)) bzero(&server_addr, sizeof(server_addr)); #else memset((char*) &server_addr, 0, sizeof(server_addr)); #endif #ifdef SOLARIS struct hostent* host=0; // Try ATM String name(getenv("HOSTNAME")); name+="-atm"; // default extension for ATM if (name.length()!=0 && (host=gethostbyname(name.chars()))==0){ // if no ATM, try regular HOSTNAME address if ((host=gethostbyname(getenv("HOSTNAME")))==0){ error("could not get host by name"); athr_exit(0); } } server_addr.sin_addr.s_addr =((struct in_addr *) host->h_addr_list[0])->s_addr; #endif server_addr.sin_family=AF_INET; server_addr.sin_port=htons(asap); while (1){ if (::bind(socketfd, (struct sockaddr*) &server_addr, sizeof(server_addr))<0){ ::close(socketfd); error("could not bind local address"); exit(1); } else break; asap++; } int reuseaddr=1; if (setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, (char*) &reuseaddr, sizeof(reuseaddr))<0){ error("can't set sender socket option (SO_REUSEADDR)"); exit(1); } if (pdu_size){ unsigned int read_size=pdu_size; if (setsockopt(socketfd,SOL_SOCKET,SO_SNDBUF,(char*)&read_size,sizeof(read_size))<0){ error("can't set socket option (SO_SNDBUF)"); exit(1); } if (setsockopt(socketfd,SOL_SOCKET,SO_RCVBUF,(char*)&read_size,sizeof(read_size))<0){ error("can't set socket option (SO_RCVBUF)"); exit(1); } } int alive=1; if (setsockopt(socketfd,SOL_SOCKET,SO_KEEPALIVE,(char*)&alive,sizeof(alive))<0){ error("can't set socket option (SO_KEEPALIVE)"); exit(1); } int error=0, error_len=sizeof(error); if (getsockopt(socketfd, SOL_SOCKET, SO_ERROR, (char*) &error, &error_len)<0){ error("can't get sender socket option (SO_ERROR)"); exit(1); } if (::listen(socketfd, 1)<0){ error("could not listen to connection"); exit(0); } } SocketTcp::~SocketTcp(){ TRACER("SocketTcp::~SocketTcp"); ::close(fd); } int SocketTcp::accept(){ DEBUGGER("int SocketTcp::accept()"); sockaddr_in client_addr; int client_len=sizeof(client_addr); #if (defined(IRIX) || defined(IRIX_PTHREAD)) bzero(&client_addr, sizeof(client_addr)); #else memset((char*) &client_addr, 0, sizeof(client_addr)); #endif if ((fd=::accept(socketfd, (struct sockaddr*) &client_addr, &client_len))<=0){ error("could not accept connection (" << itoa(errno) << ")"); athr_exit(0); } ::close(socketfd); message("received connection on TCP!"); return fd; } int SocketTcp::recv(unsigned char* data, int size){ DEBUGGER("int SocketTcp::recv(unsigned char* data, int size)"); bfr=data; read_bytes=0; do { if ((bytes=::read(fd, bfr, size-read_bytes))<=0) return bytes; bfr+=bytes; read_bytes+=bytes; } while (read_bytesh_addr_list[0])->s_addr; #endif server_addr.sin_family=AF_INET; server_addr.sin_port=htons(asap); while (1){ if (::bind(socketfd, (struct sockaddr*) &server_addr, sizeof(server_addr))<0){ ::close(socketfd); error("could not bind local address"); exit(1); } else break; asap++; } int reuseaddr=1; if (setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, (char*) &reuseaddr, sizeof(reuseaddr))<0){ error("can't set sender socket option (SO_REUSEADDR)"); exit(1); } if (pdu_size){ unsigned int read_size=pdu_size; if (setsockopt(socketfd,SOL_SOCKET,SO_SNDBUF,(char*)&read_size,sizeof(read_size))<0){ error("can't set socket option (SO_SNDBUF)"); exit(1); } if (setsockopt(socketfd,SOL_SOCKET,SO_RCVBUF,(char*)&read_size,sizeof(read_size))<0){ error("can't set socket option (SO_RCVBUF)"); exit(1); } } int alive=1; if (setsockopt(socketfd,SOL_SOCKET,SO_KEEPALIVE,(char*)&alive,sizeof(alive))<0){ error("can't set socket option (SO_KEEPALIVE)"); exit(1); } int error=0, error_len=sizeof(error); if (getsockopt(socketfd, SOL_SOCKET, SO_ERROR, (char*) &error, &error_len)<0){ error("can't get sender socket option (SO_ERROR)"); exit(1); } pcli_addr=(sockaddr*) &cli_addr; cli_len=sizeof(cli_addr); } SocketUdp::~SocketUdp(){ TRACER("SocketUdp::~SocketUdp"); ::close(fd); } int SocketUdp::accept(){ TRACER("int SocketUdp::accept()"); fd=socketfd; message("received connection on UDP!"); return fd; } int SocketUdp::recv(unsigned char* data, int size){ DEBUGGER("int SocketUdp::recv(unsigned char* data, int size)"); bfr=data; read_bytes=0; do { if ((bytes=::recvfrom(fd, (char*) bfr, size-read_bytes, 0, pcli_addr, &cli_len))==size) return bytes; bfr+=bytes; read_bytes+=bytes; } while (read_bytes0){ atm_close(dummy); // found an ATM board; thus include these while wating for connection sockets[count++]=new SocketAtmSpans(asap); sockets[count++]=new SocketAtmPvc(vci, vpi); } sockets[count]=0; #endif } SocketMulti::SocketMulti(const char* name){ TRACER("SocketMulti::SocketMulti(const char* name)"); sockets=0; socket=new SocketFile(name); count=1; } SocketMulti::~SocketMulti(){ if (sockets){ for (int i=0; sockets[i]!=0; i++) delete sockets[i]; delete[] sockets; } else delete socket; } int SocketMulti::accept(){ TRACER("int SocketMulti::accept()"); if (sockets==0) return 0; pollfd fds[SOCKETMULTI_MAX]; for (int i=0; isocketfd; fds[i].events= POLLRDNORM | POLLPRI; // POLLIN | POLLRDBAND | ); } message("waiting for connection ... "); if (poll(fds, count, -1)<0){ error("could not call poll"); exit(1); } for (int j=0; j0){ return (socket=sockets[j])->accept(); } } error("failed to find event after poll"); return -1; } @