|
Home > Archive > Unix Programming > March 2004 > Sockets and curses Query
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Sockets and curses Query
|
|
| Materialised 2004-03-19, 10:34 pm |
| Hi everyone,
Just a quick question really.
Im writing a basic client (using curses) for a simple tcp server.
The client needs to send data to the server and also recieve data from
the server.
The client reads user input using the following function:-
char *cgetline(WINDOW *win, int x, int y)
{
char *line;
int nalloc = 10;
int nch = 0;
int c;
line = malloc(nalloc + 1);
if(line == NULL){
printf("out of memory\n");
exit(1);
}
while((c = mvwgetch(win, x, y)) != EOF){
y++;
if(c == '\n')
break;
if(nch >= nalloc){
char *newp;
nalloc += 10;
newp = realloc(line, nalloc + 1);
if(newp == NULL){
printf("out of memory\n");
exit(1);
}
line = newp;
}
line[nch++] = c;
}
if(c == EOF && nch == 0){
free(line);
return NULL;
}
line[nch] = '\0';
return line;
}
The problem I am having is that I am having is the client is blocking.
i.e It waits for data before the user can send more data.
I am using select, and I understand select() can work with file
descriptors also.
Is there any way I can use FD_ISSET() with a pointer?
So that I can also monitor the the pointer to char for new information?
If not, what is the standard work around to this problem?
Thanks and sorry if this seems a dumb question, I'm slowly working my
way through Unix Network Programming. I think I may be getting a little
ahead of myself.
Mick
| |
| David Schwartz 2004-03-19, 10:34 pm |
|
"Materialised" <materialised@privacy.net> wrote in message
news:c3gcji$27lrid$1@ID-220437.news.uni-berlin.de...
> I am using select, and I understand select() can work with file
> descriptors also.
> Is there any way I can use FD_ISSET() with a pointer?
> So that I can also monitor the the pointer to char for new information?
I don't follow you at all. What do you mean by "monitor the pointer"? No
new information is going to get there unless you put it there.
You probably want to write your code as an event loop, not a single
loop. That is, your code kind of looks like this:
wait for something to happen
was it a keyboard hit? if yes, process it
is network data vailable? if yes, receive it and process it
go back to the top
DS
| |
| Materialised 2004-03-20, 10:38 am |
| David Schwartz wrote:
> "Materialised" <materialised@privacy.net> wrote in message
> news:c3gcji$27lrid$1@ID-220437.news.uni-berlin.de...
>
>
>
>
>
>
> I don't follow you at all. What do you mean by "monitor the pointer"? No
> new information is going to get there unless you put it there.
>
> You probably want to write your code as an event loop, not a single
> loop. That is, your code kind of looks like this:
>
<snip>
Yeah that Is what I have attempted to do.
But still for some reason, it hangs waiting for data from the keyboard
even when I am manually sending data from the server. Once the user hits
return in the client, then the data recieved is displayed fine.
Just a idea: Would It work better if I fork()ed and used one process for
reciving the data from the server and another process to get user input
within the client, and send to ther server?
Here is the driving loop of my program as it is now.
for(;;) {
for(i = 0; i < 1000; ++i)
buf[i] = '\0';
read_fds = master; /* We copy it because select modifies our fdset */
if(select(fdmax +1, &read_fds, NULL, NULL, NULL) == -1) {
perror("select");
exit(1);
}
if(FD_ISSET(sockfd, &read_fds)) {
if ((numbytes=recv(sockfd, buf, 1000-1, 0)) == -1) {
perror("recv");
exit(1);
} else {
attrset(COLOR_PAIR(1) | A_BOLD);
mvwprintw(mainwin, rows -4, 5, "Data From Server: %s", buf);
scroll(mainwin);
}
}
free(data);
data = cgetline(inputwin, 1, 0, 50);
len = strlen(data);
if(sendall(sockfd, data, &len) == -1) {
perror("sendall");
}
scroll(mainwin);
mvwprintw(mainwin, rows -5, 5, "Your Data: %s", data);
wrefresh(mainwin);
wrefresh(inputwin);
}
| |
| Ying-Chun Liu 2004-03-20, 10:38 am |
| Materialised wrote:
> David Schwartz wrote:
>
> <snip>
>
> Yeah that Is what I have attempted to do.
> But still for some reason, it hangs waiting for data from the keyboard
> even when I am manually sending data from the server. Once the user hits
> return in the client, then the data recieved is displayed fine.
>
> Just a idea: Would It work better if I fork()ed and used one process for
> reciving the data from the server and another process to get user input
> within the client, and send to ther server?
fork or thread is better... but not easy to use..
>
> Here is the driving loop of my program as it is now.
>
> for(;;) {
> for(i = 0; i < 1000; ++i)
> buf[i] = '\0';
>
> read_fds = master; /* We copy it because select modifies our
> fdset */
/*use timeout here..*/
struct timeval tv;
tv.tv_sec=1;
tv.tv_usec=0;
> if(select(fdmax +1, &read_fds, NULL, NULL, &tv) == -1) {
> perror("select");
> exit(1);
> }
> if(FD_ISSET(sockfd, &read_fds)) {
> if ((numbytes=recv(sockfd, buf, 1000-1, 0)) == -1) {
> perror("recv");
> exit(1);
> } else {
> attrset(COLOR_PAIR(1) | A_BOLD);
> mvwprintw(mainwin, rows -4, 5, "Data From Server: %s",
> buf);
> scroll(mainwin);
> }
> }
> free(data);
char c;
nodelay(inputwin,TRUE);
c = getch();
nodelay(inputwin,FALSE);
if (c != ERR)
{
ungetch(c);
> data = cgetline(inputwin, 1, 0, 50);
> len = strlen(data);
> if(sendall(sockfd, data, &len) == -1) {
> perror("sendall");
> }
> scroll(mainwin);
> mvwprintw(mainwin, rows -5, 5, "Your Data: %s", data);
}
> wrefresh(mainwin);
> wrefresh(inputwin);
>
> }
>
|
|
|
|
|