apps/astreamer/socket.cpp

Go to the documentation of this file.
00001 #include <string>
00002 #include <iostream>
00003 
00004 #include <sys/types.h>
00005 #include <sys/socket.h>
00006 #include <arpa/inet.h>
00007 #include <netinet/in.h>
00008 #include <unistd.h>
00009 #include <sys/poll.h>
00010 #include <errno.h>
00011 #include <fcntl.h>
00012 #include <string.h>
00013 
00014 using namespace std;
00015 
00016 #include "socket.h"
00017 #include "helpers.h"
00018 
00019 #undef RTSP_DEBUG
00020 
00021 #ifdef RTSP_DEBUG
00022         #define D(a) a
00023 #else
00024         #define D(a)
00025 #endif
00026 
00027 #define BUF_SIZE        2048
00028 
00029 TCP_Client::TCP_Client(bool enable_exception) {
00030         ex = enable_exception;
00031         fd = -1;
00032 }
00033 
00034 TCP_Client::~TCP_Client() {
00035         disconnect();
00036 }
00037 
00038 void TCP_Client::connect(string ip, string port) {
00039         if((fd = ::socket(PF_INET, SOCK_STREAM, 0)) == -1) {
00040                 cerr << "fail socket()" << endl;
00041                 throw(false);
00042         }
00043 
00044         struct sockaddr_in addr;
00045         memset(&addr, 0, sizeof(struct sockaddr_in));
00046         addr.sin_family = AF_INET;
00047         addr.sin_port = htons(::atol(port.c_str()));
00048         addr.sin_addr.s_addr = ::inet_addr(ip.c_str());
00049 
00050         if(::connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) == -1) {
00051                 cerr << "fail connect() to " << ip << ":" << port << endl;
00052                 throw(false);
00053         }
00054         // TODO: we must use size as MTU for interface... and also - checking for not single frames...
00055         buf = (char *)malloc(1500);
00056 }
00057 
00058 void TCP_Client::disconnect(void) {
00059         if(fd > 0) {
00060                 ::close(fd);
00061                 free(buf);
00062                 buf = NULL;
00063         }
00064         fd = -1;
00065 }
00066 
00067 void TCP_Client::send(const string *data, int opt) {
00068         if(::send(fd, data->c_str(), data->length(), opt) < 0) {
00069                 cerr << "fail to send(const string *)" << endl;
00070                 throw(false);
00071         }
00072 }
00073 
00074 void TCP_Client::send(const string data, int opt) {
00075         int er;
00076         if(::send(fd, data.c_str(), data.length(), opt) < 0) {
00077                 er = errno;
00078                 cerr << "fail to send(const string): " << strerror(er) << endl;
00079                 throw(false);
00080         }
00081 }
00082 
00083 void TCP_Client::send(void *data, int len, int opt) {
00084         if(::send(fd, data, len, opt) < 0) {
00085                 cerr << "fail to send(void *, len)" << endl;
00086                 throw(false);
00087         }
00088 }
00089 
00090 void TCP_Client::recv(string &r, int opt) {
00091         int l, er;
00092         if((l = ::recv(fd, buf, BUF_SIZE - 1, opt)) > 0) {
00093                 buf[l] = '\0';
00094                 r = buf;
00095         } else {
00096                 er = errno;
00097                 cerr << "fail to recv(string &): " << strerror(er) << endl;
00098                 throw (false);
00099         }
00100 }
00101 
00102 /*
00103  * Socket class...
00104  */
00105 
00106 unsigned long Socket::ip_to_number(string ip) {
00107         string left;
00108         string right;
00109         unsigned long rez = 0;
00110         while(String::split(ip, '.', left, right)) {
00111                 rez += atol(left.c_str());
00112                 rez <<= 8;
00113                 ip = right;
00114         }
00115         return rez;
00116 }
00117 
00118 bool Socket::_is_multicast(string ip) {
00119         bool rez = true;
00120         unsigned long a_min = ip_to_number("224.0.0.0");
00121         unsigned long a_max = ip_to_number("239.255.255.255");
00122         if(a_min > a_max) {
00123                 unsigned long a = a_min;
00124                 a_min = a_max;
00125                 a_max = a;
00126         }
00127         unsigned long a_ip = ip_to_number(ip.c_str());
00128         if(a_ip > a_max)
00129                 rez = false;
00130         if(a_ip < a_min)
00131                 rez = false;
00132         return rez;
00133 }
00134 
00135 Socket::Socket(string _ip, int _port, stype _type) {
00136         ip = _ip;
00137         port = _port;
00138         is_multicast = false;
00139 
00140 D(cerr << "new socket..." << endl;)
00141         _state = STATE_EMPTY;
00142 
00143         int t = 0;
00144         type = _type;
00145 
00146         struct sockaddr_in addr;
00147         memset(&addr, 0, sizeof(struct sockaddr_in));
00148         addr.sin_family = PF_INET;
00149         addr.sin_port = htons(port);
00150 
00151         switch(type) {
00152         case TYPE_TCP: {
00153                 fd = socket(PF_INET, SOCK_STREAM, 0);
00154                 int flag = 1;
00155                 setsockopt(fd, IPPROTO_IP, SO_REUSEADDR, &flag, sizeof(flag));
00156                 if(ip != "")
00157                         addr.sin_addr.s_addr = inet_addr(ip.c_str());
00158                 else
00159                         addr.sin_addr.s_addr = htonl(INADDR_ANY);
00160                 t = bind(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr));
00161 D(              cerr << "TCP ::bind() == " << t << endl;)
00162                 break;
00163         }
00164         case TYPE_UDP: {
00165                 fd = socket(PF_INET, SOCK_DGRAM, 0);
00166                 struct sockaddr_in saddr;
00167                 memset(&saddr, 0, sizeof(struct sockaddr_in));
00168                 saddr.sin_family = PF_INET;
00169                 saddr.sin_port = htons(0);
00170                 saddr.sin_addr.s_addr = htonl(INADDR_ANY);
00171                 ::bind(fd, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
00172                 addr.sin_addr.s_addr = inet_addr(ip.c_str());
00173                 t = ::connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr));
00174 D(              cerr << "::connect() == " << t << endl;)
00175                 if((is_multicast = _is_multicast(ip)) == true) {
00176                         struct ip_mreqn multiaddr;
00177                         multiaddr.imr_multiaddr.s_addr = inet_addr(ip.c_str());
00178                         multiaddr.imr_address.s_addr = htonl(INADDR_ANY);
00179                         multiaddr.imr_ifindex = 0;
00180                         setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &multiaddr, sizeof(struct sockaddr_in));
00181                 }
00182                 }
00183                 break;
00184 //      }
00185         }
00186 }
00187 
00188 Socket::Socket(int _fd, string _ip, int _port, stype _t) {
00189         _state = STATE_EMPTY;
00190 
00191         fd =_fd;
00192         ip = _ip;
00193         port = _port;
00194         type = _t;
00195 D(      cerr << "socket: ip == " << ip << "; port == " << port << endl;)
00196 }
00197 
00198 Socket::~Socket() {
00199         close(fd);
00200 }
00201 
00202 int Socket::poll(list<Socket *> &s) {
00203         struct pollfd *pfd;
00204         ssize_t s_size = s.size();
00205 
00206 D(cerr << "Socket::poll()..." << endl;)
00207         pfd = (struct pollfd *)malloc(sizeof(struct pollfd) * s_size);
00208         memset(pfd, 0, sizeof(struct pollfd) * s_size);
00209         int i = 0;
00210 D(cerr << "socket.fd == ";)
00211         for(list<Socket *>::iterator it = s.begin(); it != s.end(); it++, i++) {
00212                 pfd[i].fd = (*it)->fd;
00213 D(cerr << pfd[i].fd << "; ";)
00214 //              pfd[i].events = 0xFFFF;
00215                 pfd[i].events = POLLIN | POLLHUP;
00216                 pfd[i].revents = 0x00;
00217         }
00218 D(cerr << endl;)
00219         int p = ::poll(pfd, s_size, -1);
00220         i = 0;
00221         for(list<Socket *>::iterator it = s.begin(); it != s.end(); it++, i++) {
00222                 (*it)->_state = STATE_EMPTY;
00223 D(cerr << "revents == " << pfd[i].revents << "; POLLIN == " << POLLIN << endl;)
00224                 if(pfd[i].revents & POLLIN) {
00225                         (*it)->_state = STATE_IN;
00226 D(cerr << "STATE_IN; fd == " << (*it)->fd << "; revents == " << pfd[i].revents << endl;)
00227                 } 
00228                 if(pfd[i].revents & POLLHUP) {
00229                         (*it)->_state = STATE_DISCONNECT;
00230 D(cerr << "STATE_DISCONNECT; fd == " << (*it)->fd << "; revents == " << pfd[i].revents << endl;)
00231                 } 
00232         }
00233         free((void *)pfd);
00234         return p;
00235 }
00236 
00237 void Socket::listen(int in) {
00238         long sock_flags;
00239 
00240         sock_flags = fcntl(fd, F_GETFL);
00241         sock_flags |= O_NONBLOCK;
00242         fcntl(fd, F_SETFL, sock_flags);
00243 	::listen(fd, in);
00244 }
00245 
00246 Socket *Socket::accept(void) {
00247         int _fd;
00248         struct sockaddr_in addr;
00249         socklen_t addr_len = 0;
00250         long sock_flags;
00251         Socket *s;
00252 
00253         memset(&addr, 0, sizeof(struct sockaddr_in));
00254         addr_len = sizeof(struct sockaddr_in);
00255         _fd = ::accept(fd, (struct sockaddr *)&addr, &addr_len);
00256         if(_fd < 0)
00257                 return NULL;
00258         sock_flags = fcntl(_fd, F_GETFL);
00259         sock_flags |= O_NONBLOCK;
00260         fcntl(_fd, F_SETFL, sock_flags);
00261 D(cerr << "accept == " << _fd << "; addr_len == " << addr_len << endl;)
00262         s = new Socket(_fd, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port), type);
00263         return s;
00264 }
00265 
00266 /*
00267 bool Socket::connect(void) {
00268         struct ip_mreqn multiaddr;
00269         struct sockaddr_in ma;
00270 
00271         rtp_sock = socket(PF_INET, SOCK_DGRAM, 0);
00272         multiaddr.imr_address.s_addr = htonl(INADDR_ANY);
00273         memcpy(&multiaddr.imr_multiaddr.s_addr, multicast_ip, 4);
00274         multiaddr.imr_ifindex = 0;
00275         if(setsockopt(rtp_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &multiaddr, sizeof(struct sockaddr_in)) != 0)
00276                 return false;
00277         rtp_sock = socket(PF_INET, SOCK_DGRAM, 0);
00278         ma.sin_family = AF_INET;
00279         ma.sin_addr.s_addr = INADDR_ANY;
00280         ma.sin_port = htons(RTP_MCAST_SERVER_PORT);
00281         if(bind(rtp_sock, (const struct sockaddr*)&ma, sizeof(struct sockaddr_in)) != 0)
00282                 return false;
00283         ma.sin_family = AF_INET;
00284         memcpy(&ma.sin_addr.s_addr, multicast_ip, 4);
00285         ma.sin_port = htons(RTP_MCAST_CLIENT_PORT);
00286         if(connect(rtp_sock, (const struct sockaddr*)&ma, sizeof(struct sockaddr_in)) != 0)
00287                 return false;
00288         return true;
00289 }
00290 */
00291 
00292 bool Socket::recv(string &rez) {
00293         rez = "???";
00294         char buf[1501];
00295         int l = 0;
00296         buf[0] = '\0';
00297 
00298         if((l = ::recv(fd, buf, 1500, MSG_NOSIGNAL | MSG_DONTWAIT)) > 0) {
00299                 buf[l] = '\0';
00300                 rez = buf;
00301 D(cerr << "read - ok!"<< endl;)
00302                 return true;
00303         } else if(l == 0) {
00304                 rez = "";
00305                 return true;
00306         }
00307         rez = "";
00308         return false;
00309 }
00310 
00311 bool Socket::send(void *data, int len) {
00312         return (::send(fd, data, len, MSG_NOSIGNAL | MSG_DONTWAIT) > 0);
00313 }
00314 
00315 bool Socket::send(const string *data) {
00316         if(::send(fd, data->c_str(), data->length(), 0) > 0)
00317                 return true;
00318         return false;
00319 }
00320 
00321 bool Socket::send(const string data) {
00322         if(::send(fd, data.c_str(), data.length(), MSG_NOSIGNAL | MSG_DONTWAIT) > 0)
00323                 return true;
00324         return false;
00325 }
00326 
00327 uint16_t in_chksum(const uint16_t *addr, register uint32_t len) {
00328         int32_t nleft = len;
00329         const uint16_t *w = addr;
00330         uint16_t answer;
00331         int32_t sum = 0;
00332 
00333         while(nleft > 1)  {
00334                 sum += *w++;
00335                 nleft -= 2;
00336         }
00337         if(nleft == 1)
00338                 sum += htons(*(uint8_t  *)w << 8);
00339         sum = (sum >> 16) + (sum & 0xffff);     /* add hi 16 to low 16 */
00340         sum += (sum >> 16);                     /* add carry */
00341         answer = ~sum;                          /* truncate to 16 bits */
00342         return answer;
00343 }
00344 
00345 bool Socket::send2v(void **v_ptr, int *v_len) {
00346         struct iovec iov[2];
00347         int iovcnt = sizeof(iov) / sizeof(struct iovec);
00348         iov[0].iov_base = v_ptr[0];
00349         iov[0].iov_len = v_len[0];
00350         iov[1].iov_base = v_ptr[1];
00351         iov[1].iov_len = v_len[1];
00352         if(::writev(fd, iov, iovcnt))
00353                 return true;
00354         return false;
00355 }
00356 
00357 bool Socket::send3v(void **v_ptr, int *v_len) {
00358         struct iovec iov[3];
00359         int iovcnt = sizeof(iov) / sizeof(struct iovec);
00360         iov[0].iov_base = v_ptr[0];
00361         iov[0].iov_len = v_len[0];
00362         iov[1].iov_base = v_ptr[1];
00363         iov[1].iov_len = v_len[1];
00364         iov[2].iov_base = v_ptr[2];
00365         iov[2].iov_len = v_len[2];
00366         if(::writev(fd, iov, iovcnt))
00367                 return true;
00368         return false;
00369 }

Generated on Fri Nov 28 00:06:21 2008 for elphel by  doxygen 1.5.1