LinuxQuestions.org
Support LQ: Use code LQ3 and save $3 on Domain Registration
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
LinkBack Search this Thread
Old 03-12-2005, 04:36 PM   #1
bob66
LQ Newbie
 
Registered: Jan 2005
Posts: 14

Rep: Reputation: 0
C socket non-blocking


I have a problem with a client that i am writing (tcp). What i need to do is to read a variable amount of text from a server, and possible a LOT of text. However, If i read from a while loop, then the client hangs, obviously because the client does not know how much to read. But if I don't read in a while loop, then the server may send too much data and fill up my buffer. How can I go about this without experiencing the above two problems. Here are the 2 cases:

loop:
Code:
...
char buff;
while ((numread = read(sock_fd, &buff, 1)) > 0) {
   write(out_fd, &buff, 1);
}
...
no loop:
Code:
...
char *buff = malloc(MAX_BUFF);
numread = read(sock_fd, buff, MAX_BUFF);
write(out_fd, buff, numread);
free(buff);
...
I am not sure what techiques are usually employed here to accomplish what I am doing. Any advice would be appreciated.

By the way, is the first method above called blocking?
 
Old 03-13-2005, 10:21 AM   #2
aluser
Member
 
Registered: Mar 2004
Location: Massachusetts
Distribution: Debian
Posts: 557

Rep: Reputation: 42
they're both blocking, they just work a bit differently.

The second is almost certainly not what you want because read() only waits until *some* data is ready for reading from the socket and returns when it's read some. It doesn't necessarily read as many bytes as you asked for. (That's why it returns how many it's read.)

If you really want to do nonblocking reads, you can set the socket nonblocking with (I think)
Code:
fcntl(sock_fd, F_SETFL, O_NONBLOCK)
what this means is that, if you read() on the socket and there is no data currently availabe, read returns -1 and sets errno to EAGAIN, rather than waiting for more data from the server. If your program has nothing to do while it waits for more data from the server, then it shouldn't have used nonblocking mode!

A loop which gives equivalent results to your first loop, but is more efficient, would look like
Code:
char buf[BUFLEN];
int numread;
while ((numread = read(sock_fd, buf, BUFLEN)) > 0) {
    if (write(out_fd, buf, numread) != numread)
        err(1, "problem with write()!");
}
if (numread != 0)
    err(1, "read errored");
Actually, to be fully correct you would need to call write() inside a loop, since it is not guaranteed to write all the bytes you ask it to. In practice, it'll write what you ask if you're writing to a file, but not necessarily if you write to a socket.

Now, this will still hang until it gets EOF from the server. If you want that not to happen, you can either use nonblocking mode and go do something useful whenever read errors with EAGAIN, break your program into threads and have one of them block on read() while others do something useful, or use select() or poll() to decide when to read.

If the end of the server's data is signalled by something other than EOF, then you need to build into your protocol a way for the client to know when it's done reading. Common ways to do this are to have the server start a message with an integer giving the length of the following message, or end the message with a special character (say a newline if that fits what you're doing)

hm, hope some of that was on target.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
cannot read data at server socket, though client socket sends it jacques83 Linux - Networking 0 11-15-2005 01:58 PM
AMD socket A, socket 754 darkangel29 Linux - Hardware 1 10-11-2005 09:56 AM
Unable to connect to UNIX socket /tmp/.esd/socket error while using grip dr_zayus69 Linux - Software 4 08-23-2005 07:28 PM
Help on socket Programming non-blocking io mounterriver Linux - Networking 3 03-21-2005 07:43 AM
Packet socket and socket filtring Baran Linux - Newbie 4 10-09-2003 07:16 AM


All times are GMT -5. The time now is 12:53 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration