• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Simultaneous read() and write() on same TCP/IP socket
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Simultaneous read() and write() on same TCP/IP socket


  • Subject: Re: Simultaneous read() and write() on same TCP/IP socket
  • From: Jonathon Kuo <email@hidden>
  • Date: Fri, 31 Dec 2010 12:09:44 -0800

On Dec 14, 2010, at 1:10 AM, Quinn The Eskimo! wrote:

> If you're still working on the socket-to-socket bridging code, I recommend you look at non-blocking sockets with GCD.  That's how I'd tackle this problem on modern Apple OSes.

Taking Quinn's advice, I've implemented my message receiver / forwarder using GCD, blocks, and TCP sockets. Everything works!! Sockets get closed when clients depart, new connections get established on new threads when clients connect, etc. I really didn't expect it to all just work. GCD and blocks are really slick!

However... there is one not so small problem.

Once a client connects, the program is waiting on a read() for a message from the client, it takes up about 100% of 1 cpu just sitting there, idle. If two clients are 'connected' such that the program has two GCD threads waiting on read()s, it takes 200% cpu, etc. In the debugger, the thread(s) that are taking all the cpu are:

<com.apple.main-thread>
0 mach_msg_trap
1 mach_msg
2 _CFRunLoopRun
3 CFRunLoopRunSpecific
4 -[NSRunLoop(NSRunLoop) runMode:beforeDate:]
5 -[NSRunLoop(NSRunLoop) run]
6 main

I've profiled the program in Instruments, but it just shows this same thread (one per read() call) taking up 30% the cpu, a kevent thread taking up 30%, and a read() thread taking up 30%. These last two thread backtraces end in _dispatch_worker_thread2.

I've attached the flow of the code below. Perhaps I'm doing something very obviously wrong?
Thanks!
-Jon

---------------------------------------

main.m

[[myobj alloc] init];
[myobj startProcessing];
[[NSRunLoop currentRunLoop] run];

---------------------------------------

[myobj startProcessing]

    listensocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);  // set up socket
    setsockopt(listensocket,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int));  // set it nohang
    fcntl(listensocket,F_SETFL,O_NONBLOCK);  // set it non-blocking
    bind(listensocket,(struct sockaddr *)&listen_addrin,sizeof(listen_addrin));  // bind the socket
    listen(listensocket,5);  // set to listen mode

    dispatch_source_t lstn_src = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ,listensocket,0,globalQueue);
    dispatch_source_set_event_handler((dispatch_source_t)lstn_src, ^{
      new_socket = accept(listensocket,(struct sockaddr *)&temp_addrin,&temp_len);  // wait for incoming cnx
      setsockopt(new_socket,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int));  // set new socket to nohang
      fcntl(new_socket,F_SETFL,O_NONBLOCK);  // set it to non-blocking
      [self processNewConnection];  // invoke method below
    });
    dispatch_resume(lstn_src);


[myobj processNewConnection]

    dispatch_source_t newsrc = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ,new_socket,0,globalQueue );
    dispatch_source_set_event_handler(newsrc, ^{
      for(;;) {
        read(new_socket,inbox,&bsize);  // read from the socket
        // prepare response
        write(new_socket,outbuf,baize); // write to the socket
      }
      dispatch_source_cancel(newsrc);
      return;
    }); // dispatch
    dispatch_source_set_cancel_handler(newsrc, ^{
      close(new_socket);
      dispatch_release(newsrc);
    });
    dispatch_resume(newsrc);
---------------------------------------

 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

References: 
 >Simultaneous read() and write() on same TCP/IP socket (From: Jonathon Kuo <email@hidden>)
 >Re: Simultaneous read() and write() on same TCP/IP socket (From: "Quinn \"The Eskimo!\"" <email@hidden>)

  • Prev by Date: Using Unix Domain Sockets
  • Previous by thread: Re: Simultaneous read() and write() on same TCP/IP socket
  • Next by thread: TCP SYN packet not send after ARP
  • Index(es):
    • Date
    • Thread