Commits

Martin Gergov committed cf69240

UDT listener works..

Comments (0)

Files changed (7)

examples/appclient.cpp

+#ifndef WIN32
+   #include <unistd.h>
+   #include <cstdlib>
+   #include <cstring>
+   #include <netdb.h>
+#else
+   #include <winsock2.h>
+   #include <ws2tcpip.h>
+   #include <wspiapi.h>
+#endif
+#include <iostream>
+#include <udt.h>
+
+using namespace std;
+
+#ifndef WIN32
+void* monitor(void*);
+#else
+DWORD WINAPI monitor(LPVOID);
+#endif
+
+int main(int argc, char* argv[])
+{
+   if ((3 != argc) || (0 == atoi(argv[2])))
+   {
+      cout << "usage: appclient server_ip server_port" << endl;
+      return 0;
+   }
+
+   // use this function to initialize the UDT library
+   UDT::startup();
+
+   struct addrinfo hints, *local, *peer;
+
+   memset(&hints, 0, sizeof(struct addrinfo));
+
+   hints.ai_flags = AI_PASSIVE;
+   hints.ai_family = AF_INET;
+   hints.ai_socktype = SOCK_DGRAM;
+   //hints.ai_socktype = SOCK_DGRAM;
+
+   if (0 != getaddrinfo(NULL, "9000", &hints, &local))
+   {
+      cout << "incorrect network address.\n" << endl;
+      return 0;
+   }
+
+   UDTSOCKET client = UDT::socket(local->ai_family, local->ai_socktype, local->ai_protocol);
+
+   // UDT Options
+   //UDT::setsockopt(client, 0, UDT_CC, new CCCFactory<CUDPBlast>, sizeof(CCCFactory<CUDPBlast>));
+   //UDT::setsockopt(client, 0, UDT_MSS, new int(9000), sizeof(int));
+   //UDT::setsockopt(client, 0, UDT_SNDBUF, new int(10000000), sizeof(int));
+   //UDT::setsockopt(client, 0, UDP_SNDBUF, new int(10000000), sizeof(int));
+
+   // Windows UDP issue
+   // For better performance, modify HKLM\System\CurrentControlSet\Services\Afd\Parameters\FastSendDatagramThreshold
+   #ifdef WIN32
+      UDT::setsockopt(client, 0, UDT_MSS, new int(1052), sizeof(int));
+   #endif
+
+   // for rendezvous connection, enable the code below
+   /*
+   UDT::setsockopt(client, 0, UDT_RENDEZVOUS, new bool(true), sizeof(bool));
+   if (UDT::ERROR == UDT::bind(client, local->ai_addr, local->ai_addrlen))
+   {
+      cout << "bind: " << UDT::getlasterror().getErrorMessage() << endl;
+      return 0;
+   }
+   */
+
+   freeaddrinfo(local);
+
+   if (0 != getaddrinfo(argv[1], argv[2], &hints, &peer))
+   {
+      cout << "incorrect server/peer address. " << argv[1] << ":" << argv[2] << endl;
+      return 0;
+   }
+
+   // connect to the server, implict bind
+   if (UDT::ERROR == UDT::connect(client, peer->ai_addr, peer->ai_addrlen))
+   {
+      cout << "connect: " << UDT::getlasterror().getErrorMessage() << endl;
+      return 0;
+   }
+
+   freeaddrinfo(peer);
+
+   // using CC method
+   //CUDPBlast* cchandle = NULL;
+   //int temp;
+   //UDT::getsockopt(client, 0, UDT_CC, &cchandle, &temp);
+   //if (NULL != cchandle)
+   //   cchandle->setRate(500);
+
+   int size = 10000;
+   char* data = new char[size];
+
+   // #ifndef WIN32
+   //    pthread_create(new pthread_t, NULL, monitor, &client);
+   // #else
+   //    CreateThread(NULL, 0, monitor, &client, 0, NULL);
+   // #endif
+
+   // for (int i = 0; i < 1000000; i ++)
+   // {
+   //    int ssize = 0;
+   //    int ss;
+   //    while (ssize < size)
+   //    {
+   //       if (UDT::ERROR == (ss = UDT::send(client, data + ssize, size - ssize, 0)))
+   //       {
+   //          cout << "send:" << UDT::getlasterror().getErrorMessage() << endl;
+   //          break;
+   //       }
+
+   //       ssize += ss;
+   //    }
+
+   //    if (ssize < size)
+   //       break;
+   // }
+   if (UDT::sendmsg(client, "bagger", 7, 1000, true) == UDT::ERROR){
+     cout << "send:" << UDT::getlasterror().getErrorMessage() << endl;
+   }
+   if (UDT::recvmsg(client, data, size) == UDT::ERROR){
+     cout << "recv:" << UDT::getlasterror().getErrorMessage() << endl;
+   }
+   cout << data << endl;
+
+   UDT::close(client);
+
+   delete [] data;
+
+   // use this function to release the UDT library
+   UDT::cleanup();
+
+   return 1;
+}
+
+#ifndef WIN32
+void* monitor(void* s)
+#else
+DWORD WINAPI monitor(LPVOID s)
+#endif
+{
+   UDTSOCKET u = *(UDTSOCKET*)s;
+
+   UDT::TRACEINFO perf;
+
+   cout << "SendRate(Mb/s)\tRTT(ms)\tCWnd\tPktSndPeriod(us)\tRecvACK\tRecvNAK" << endl;
+
+   while (true)
+   {
+      #ifndef WIN32
+         sleep(1);
+      #else
+         Sleep(1000);
+      #endif
+
+      if (UDT::ERROR == UDT::perfmon(u, &perf))
+      {
+         cout << "perfmon: " << UDT::getlasterror().getErrorMessage() << endl;
+         break;
+      }
+
+      cout << perf.mbpsSendRate << "\t\t" 
+           << perf.msRTT << "\t" 
+           << perf.pktCongestionWindow << "\t" 
+           << perf.usPktSndPeriod << "\t\t\t" 
+           << perf.pktRecvACK << "\t" 
+           << perf.pktRecvNAK << endl;
+   }
+
+   #ifndef WIN32
+      return NULL;
+   #else
+      return 0;
+   #endif
+}
+#include <unistd.h>
+#include <cstdlib>
+#include <cstring>
+#include <netdb.h>
+#include <iostream>
+#include <fcntl.h>
+#include <udt.h>
+#include <iterator> //for std::ostream_iterator
+#include <algorithm> //for std::copy
+
+using namespace std;
+
+void* recvdata(void*);
+
+int main(int argc, char* argv[])
+{
+  UDT::startup();
+  addrinfo hints;
+  addrinfo* res;
+
+  memset(&hints, 0, sizeof(struct addrinfo));
+
+  hints.ai_flags = AI_PASSIVE;
+  hints.ai_family = AF_INET;
+  hints.ai_socktype = SOCK_DGRAM;
+
+  string service = "9000";
+
+  if (getaddrinfo(NULL, service.c_str(), &hints, &res) != 0)
+  {
+     cout << "illegal port number or port is busy.\n" << endl;
+     return 1;
+  }
+
+  UDTSOCKET serv = UDT::socket(res->ai_family,
+			       res->ai_socktype,
+			       res->ai_protocol);
+
+  bool block = false;
+
+  UDT::setsockopt(serv, 0, UDT_SNDSYN, &block, sizeof(bool));
+  UDT::setsockopt(serv, 0, UDT_RCVSYN, &block, sizeof(bool));
+
+  if (UDT::ERROR == UDT::bind(serv, res->ai_addr, res->ai_addrlen))
+  {
+    cout << "bind: " << UDT::getlasterror().getErrorMessage() << endl;
+    return 1;
+  }
+
+  freeaddrinfo(res);
+  
+  if (UDT::ERROR == UDT::listen(serv, 10))
+  {
+      cout << "listen: " << UDT::getlasterror().getErrorMessage() << endl;
+      return 1;
+  }
+
+  //cout << "Hello world!" << endl;
+
+  sockaddr_storage clientaddr;
+  int addrlen = sizeof(clientaddr);
+
+  UDTSOCKET recver;
+
+  int poll = UDT::epoll_create();
+  int events = UDT_EPOLL_IN | UDT_EPOLL_ERR;
+  
+  int res1;
+  int addrlen1;
+  set<UDTSOCKET> udtset;
+
+  cout << "POLL:" << poll << endl;
+  UDT::epoll_add_usock(poll, serv, &events);
+
+  int len = 1000;
+  char* buff = new char[len];
+
+  while(true)
+  {
+    
+    res1 = UDT::epoll_wait(poll, &udtset, NULL, 1000);
+    cout << "SET:";
+    copy(
+        udtset.begin(),
+        udtset.end(),
+        ostream_iterator<UDTSOCKET>(cout, " ")
+    );
+    cout << endl;
+    // if (res1 != 0)
+    // {
+    //   addrlen1 = sizeof(sockaddr);
+    //   getaddrinfo(NULL, service.c_str(), &hints, &res);
+    //   UDTSOCKET clientsocket = UDT::accept(serv, (sockaddr*)&clientaddr, &addrlen);
+      
+    //   if (UDT::recvmsg(clientsocket, buff, len) == UDT::ERROR){
+    // 	cout << "recv: " << UDT::getlasterror().getErrorMessage() << endl;
+    //   }
+    //   UDT::sendmsg(clientsocket, "bagger", 7, -1, true);
+
+    //   cout << "BUFF:" << buff << endl;
+
+    //   if (!udtset.empty())
+    // 	cout << "Hello!" << endl;
+    //   cout << "Result from events:" << res1 << endl;
+    // }
+  }
+
+  delete [] buff;
+  UDT::close(serv);
+
+  UDT::cleanup();
+
+  
+  return 0;
+}
+from udt4 import socket, listen, UDTepoll, bind, recvmsg, UDTException
+from udt4 import startup, cleanup, accept, UDT_EPOLL_IN, UDT_EPOLL_OUT, UDT_EPOLL_ERR
+from udt4 import EASYNCRCV, sendmsg
+from socket import AF_INET, SOCK_DGRAM, AI_PASSIVE
+import udt4
+from udt4.pyudt import UdtSocket
+import gc
+
+ok = True
+startup()
+poller = UDTepoll()
+s = UdtSocket(AF_INET, SOCK_DGRAM, AI_PASSIVE)
+print s.UDTSOCKET
+s.setblocking(False)
+s.bind(("127.0.0.1", 5000))
+poller.add_usock(s.UDTSOCKET, UDT_EPOLL_IN)
+s.listen(20)
+
+try:
+    while True:
+        sets = poller.wait(True, True, 1000, False, False)
+        print sets
+        
+        for socket in sets[0]:
+            print socket
+            # if (socket.UDTSOCKET == s.UDTSOCKET.UDTSOCKET):
+            #     sock, host = accept(socket)
+            #     print sock, host
+            #     sock = UdtSocket(_sock=sock)
+            #     sock.setblocking(False)
+            #     poller.add_usock(sock.UDTSOCKET, UDT_EPOLL_IN | UDT_EPOLL_ERR)
+            # else:
+            #     print "READ:", socket
+            #     try:
+            #         print recvmsg(socket.UDTSOCKET, 7)
+            #     except udt4.UDTException as ue:
+            #         print "ERR:",ue
+            #     poller.remove_usock(socket.UDTSOCKET, UDT_EPOLL_IN | UDT_EPOLL_ERR)
+                    
+except KeyboardInterrupt:
+    exit("Bye!")
+poller.remove_usock(s.UDTSOCKET)
+
+cleanup()

examples/client.py

+from udt4 import startup, cleanup, accept, UDT_EPOLL_IN, UDT_EPOLL_OUT, UDT_EPOLL_ERR
+from socket import AF_INET, SOCK_DGRAM, AI_PASSIVE
+import udt4
+from udt4.pyudt import UdtSocket
+
+# startup()
+# s = UdtSocket(AF_INET, SOCK_DGRAM, AI_PASSIVE)
+# print s.UDTSOCKET
+# #s.setblocking(True)
+# s.connect(("127.0.0.1", 5000))
+# s.sendmsg("Hello", None, -1, True)
+# print "entering loop..."
+# s.sendmsg("Pwwww", None, -1, True)
+# s.sendmsg("Hello", None, -1, True)
+# print "entering loop..."
+# s.sendmsg("Pwwww", None, -1, True)
+# s.sendmsg("Hello", None, -1, True)
+# print "entering loop..."
+# s.sendmsg("Pwwww", None, -1, True)
+# try:
+#     while True:
+#         print s.recvmsg(8)
+# except KeyboardInterrupt:
+#     exit("Bye!")
+# cleanup()
+import sys
+sys.path.append("../")
+
+from udt4twisted import udtepollreactor
+udtepollreactor.install()
+
+from twisted.python import log
+from twisted.internet import reactor, defer
+from twisted.internet.protocol import DatagramProtocol
+from twisted.python import log
+log.startLogging(sys.stdout)
+
+
+class UDTClient(DatagramProtocol):
+
+    def doSend(self):
+        self.transport.write("?>!", ("127.0.0.1", 5000))
+
+    def datagramReceived(self, data, (host, port)):
+        print "Received %r" % data
+        self.transport.write("?>!", ("127.0.0.1", 5000))
+
+
+
+udtclient = UDTClient()
+reactor.connectUDT("127.0.0.1", 5000, udtclient)
+reactor.callWhenRunning(udtclient.doSend)
+reactor.run()

examples/sockrecv.py

             s.listen(20)
             ok = False
 
-        #print sets
         for socket in sets[0]:
             #print socket
             print "!", socket.UDTSOCKET, s.UDTSOCKET.UDTSOCKET

udt4twisted/udt.py

 import sys 
-
 import time 
 import struct
 import socket
 from zope.interface import implementer
 from twisted.internet import fdesc
-from twisted.internet import base, defer, address, udp
+from twisted.internet import base, defer, address, udp, tcp
 from twisted.python import log, failure
 from twisted.internet import abstract, error, interfaces
 import udt4 as udt
 _sockErrReadIgnore = [EAGAIN, EINTR, EWOULDBLOCK]
 _sockErrReadRefuse = [ECONNREFUSED]
 
+def find_key(dic, val):
+    """
+    From http://www.daniweb.com/software-development/python/code/217019/search-a-python-dictionary-both-ways
+    return the key of dictionary dic given the value
+    """
+    return [k for k, v in dic.iteritems() if v == val][0]
+
 
 @implementer(
     interfaces.IListeningPort, interfaces.IUDPTransport,
         print "1"
         return s
 
+    def connect(self, host, port):
+        """
+        Connect to a remote host.
+        """
+        if self._connectedAddr:
+            raise RuntimeError("already connected, reconnecting is not currently supported")
+        if not abstract.isIPAddress(host):
+            raise ValueError("please pass only IP addresses, not domain names")
+
+        self.createInternetSocket()
+        self._connectedAddr = (host, port)
+        self.socket.connect((host, port))
+
 
     def _bindSocket(self):
         """
             print "recv from:", fd, " size:", udt.UDT_RCVDATE
             #FIXME
             data = udt.recvmsg(fd, udt.UDT_RCVDATE)
-            addr = self.addresses[fd]
+            addr = self.addresses[fd.UDTSOCKET][1]
         except udt.UDTException as ue:
-            print "!!!!"
-            return
+            return ue
         except socket.error as se:
             pass
         else:
-            read += len(data)
+            #read += len(data)
             try:
                 self.protocol.datagramReceived(data, addr)
             except:
                 log.err()
+                
+    def write(self, datagram, addr=None):
+        """
+        Write datagram to address.
+        @type datagram: C{str}
+        @param datagram: The datagram to be sent.
+
+        @type addr: C{tuple} containing C{str} as first element and C{int} as
+            second element, or C{None}
+        @param addr: A tuple of (I{stringified dotted-quad IP address},
+            I{integer port number}); can be C{None} in connected mode.
+        """
+        if self._connectedAddr:
+            print "Connected Address not implemented!"
+            # assert addr in (None, self._connectedAddr)
+            # try:
+            #     return self.socket.send(datagram)
+            # except socket.error as se:
+            #     no = se.args[0]
+            #     if no == EINTR:
+            #         return self.write(datagram)
+            #     elif no == EMSGSIZE:
+            #         raise error.MessageLengthError("message too long")
+            #     elif no == ECONNREFUSED:
+            #         self.protocol.connectionRefused()
+            #     else:
+            #         raise
+        else:
+            assert addr != None
+            if not addr[0].replace(".", "").isdigit() and addr[0] != "<broadcast>":
+                warnings.warn("Please only pass IPs to write(), not hostnames",
+                              DeprecationWarning, stacklevel=2)
+            try:
+                socket = [v[0] for k, v in self.addresses.iteritems() if  v[1] == addr][0]
+
+                return udt.sendmsg(socket, datagram, len(datagram))
+            # except socket.error as se:
+            #     no = se.args[0]
+            #     if no == EINTR:
+            #         return self.write(datagram, addr)
+            #     elif no == EMSGSIZE:
+            #         raise error.MessageLengthError("message too long")
+            #     elif no == ECONNREFUSED:
+            #         # in non-connected UDP ECONNREFUSED is platform dependent, I
+            #         # think and the info is not necessarily useful. Nevertheless
+            #         # maybe we should call connectionRefused? XXX
+            #         return
+            #     else:
+            #         raise
+            except KeyError:
+                print "No key found!"
+            except udt.UDTException:
+                print "!!!"
+        
 
 
     def _connectToProtocol(self):

udt4twisted/udtepollreactor.py

         @return: object which provides L{IListeningPort}.
         """
 
+    def connectUDT(host,
+                   port,
+                   factory,
+                   timeout,
+                   bindAddress):
+        """
+        Connects a given ClientFactory to a remote host
+        """
+
 @implementer(IReactorFDSet)
 class _UDTContinuousPolling(_ContinuousPolling):
     _POLL_DISCONNECTED = (udt4.ECONNLOST | udt4.UDT_EPOLL_ERR)
         Initialize epoll object.
         """
         udt4.startup()
-
-        print "4"
         self._poller = udt4.UDTepoll()
         self._reads = {}
         self._writes = {}
         self._selectables = {}
-        #TEST
-        # self.tests = UdtSocket(s.AF_INET, s.SOCK_DGRAM, s.AI_PASSIVE)
-        # self.tests.setblocking(False)
-        # self.tests.bind(("127.0.0.1", 9000))
-        # self.tests.listen(30)
-
-        # self._poller.add_usock(self.tests.UDTSOCKET, self._POLL_IN)
-        # try:
-        #     while True:
-        #         sets = self._poller.wait(True, True, 1000, False, False)
-        #         print sets
-        #         for socket in sets[0]:
-        #             #print socket
-        #             if (socket.UDTSOCKET == self.tests.UDTSOCKET.UDTSOCKET):
-        #                 sock, host = accept(socket)
-        #                 print sock, host
-        #                 sock = UdtSocket(_sock=sock)
-        #                 sock.setblocking(False)
-        #                 #poller.add_usock(sock.UDTSOCKET, UDT_EPOLL_IN | UDT_EPOLL_ERR)
-        # except KeyboardInterrupt:
-        #     exit("Bye!")
-        #ENDTEST
-
+        self._udtsockets = {}
         self._continuousPolling = _UDTContinuousPolling(self)
-        #TEST
-        # if self.tests:
-        #     self.sock = UdtSocket(s.AF_INET, s.SOCK_DGRAM, s.AI_PASSIVE)
-        #     self.sock.setblocking(False)
-        #     self.sock.bind(("127.0.0.1", 9000))
-        #     self.sock.listen(30)
-        #     self._poller.add_usock(self.sock.UDTSOCKET, self._POLL_IN)
-
-        #     while True:
-        #         sets = self._poller.wait(True, True, 1000, False, False)
-        #         print sets, "!"
-        #         for socket in sets[0]:
-        #                 #print socket
-        #             if (socket.UDTSOCKET == self.sock.UDTSOCKET.UDTSOCKET):
-        #                 sock, host = accept(socket)
-        #                 print sock, host
-        #                 sock = UdtSocket(_sock=sock)
-        #                 sock.setblocking(False)
-        #                 self.tests = False
-        #                 exit()
-        #ENDTEST
         posixbase.PosixReactorBase.__init__(self)
         self.addSystemEventTrigger("after", "shutdown", udt4.cleanup)
 
             else:
                 
                 if isinstance(xer, udt.Port):
-                    #TEST
-                    self.tests = True
-                    self.sock = fd
-                    #ENDTEST
                     print "ADDING U:", fd, "With flags:", flags
                     self._poller.add_usock(fd, flags)
-                    print "5"
                 else:
                     print "ADDING S:", fd, "With flags:", flags
                     self._poller.add_ssock(fd, flags)
         _drdw = self._doReadOrWrite
         for fd in set:
             try:
-                if self.tests:
-                    print fd.UDTSOCKET, self._selectables
-                    self.tests = False
                 selectable = self._selectables[fd.UDTSOCKET]
                 print "FD:", fd, "SELECT:", selectable
                 socket, addr = accept(fd)
                 print socket, addr
-                selectable.addresses[fd] = addr
+                selectable.addresses[socket.UDTSOCKET] = (socket, addr)
+                self._udtsockets[socket.UDTSOCKET] = selectable
                 socket = UdtSocket(_sock=socket)
                 socket.setblocking(False)
                 self._poller.add_usock(socket.UDTSOCKET,
                                        self._POLL_IN | self._POLL_DISCONNECTED)
             except KeyError:
-
-                # log.callWithLogger(selectable, _drdw, selectable,
-                #                    socket,
-                #                    event)
-                pass
+                if self._udtsockets.has_key(fd.UDTSOCKET):
+                    selectable = self._udtsockets[fd.UDTSOCKET]
+                    log.callWithLogger(selectable,
+                                       _drdw,
+                                       selectable,
+                                       fd,
+                                       event)
             else:
                 pass
 
 
         #handle UDT sockets
         uread, uwrite = l[:2]
-        #print uread, uwrite, timeout
+        print uread, uwrite, timeout
         self._handleUDTReadSocketSet(uread, self._POLL_IN)
         self._handleUDTWriteSocketSet(uwrite, self._POLL_OUT)
 
                 why = sys.exc_info()[1]
                 log.err()
         if why:
+            if isinstance(fd, udt4.UDTSOCKET):
+                if why[0] == 6002:
+                    self._poller.remove_usock(fd, self._POLL_IN | self._POLL_DISCONNECTED)
+                return
             self._disconnectSelectable(selectable, why, inRead)
 
 
 
     doIteration = doPoll
 
+    def connectUDT(self,
+                   host,
+                   port,
+                   protocol,
+                   bindAddress = (0, "127.0.0.1")):
+
+        c = udt.Port(bindAddress[0], protocol, bindAddress[1],
+                     maxPacketSize, self, 0)
+        c.connect(host, port)
+        return c
+
 
 def install():
     """