Re: select(), sending and receiving data
- From: Pascal Bourguignon <spam@xxxxxxxxxxxxxxxx>
- Date: Mon, 26 Dec 2005 11:26:30 +0100
Markus Pitha <markus@xxxxxxxxxx> writes:
> Hello,
>
> I'm trying to write a little server and a corresponding client. The
> server runs without any problems. I tried to connect with telnet and the
> telnet client was able to receive the "Welcoming messages" of the server
> as well as I could see the typed data of the client appearing on the
> server stdout, as it was intended.
> Unfortunately I have problems with my client. I am able to send data to
> the server, but I can not receive any data. After my research I came to
> the conclusion that select() would be able to handle this, but obviously
> I did do something wrong.
> Can anybody tell me why I can not receive any data from the server? (So
> recv() doesn't work in the program, but send() works)
> Here is the client script:
You need to let your editor indent correctly your code.
You need to reset the fd sets everytime.
You need to flush the output.
You need to avoid waiting for received packets (unless you mean it, it
depends on your protocol).
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
int main(int argc, char *argv[]) {
int sock, bytes;
struct sockaddr_in srv;
char stdinbuffer[256];
fd_set readfds, writefds;
struct timeval tv;
FD_ZERO(&readfds);
FD_ZERO(&writefds);
tv.tv_sec = tv.tv_usec = 0;
if (argc != 3) {
fprintf(stderr, "usage: %s host port\n", argv[0]);
return 1;
}
if ( (sock = socket(AF_INET, SOCK_STREAM, 0) ) == -1 ){
perror("socket failed()");
exit(1);
}
srv.sin_family = AF_INET;
srv.sin_addr.s_addr = inet_addr(argv[1]);
srv.sin_port = htons( (unsigned short int) atol(argv[2]) );
if (connect(sock, (struct sockaddr *)&srv, sizeof(srv)) == -1){
perror("connect failed()");
exit(1);
}
while (1) {
FD_ZERO(&readfds); FD_SET(sock, &readfds);
FD_ZERO(&writefds); FD_SET(sock, &writefds);
select(sock+1, &readfds, &writefds, NULL, &tv);
if (FD_ISSET(sock, &readfds) ) {
while((bytes=recv(sock,stdinbuffer,sizeof(stdinbuffer)-1,
MSG_DONTWAIT))>0){
stdinbuffer[bytes] = '\0';
printf("%s", stdinbuffer);fflush(stdout);
}
if (bytes == -1){
perror ("recv() in FD_ISSET");
}
}
if (FD_ISSET(sock, &writefds) ) {
printf("> ");fflush(stdout);
fgets(stdinbuffer, 255, stdin);
if (send(sock, stdinbuffer, strlen(stdinbuffer), 0 ) == -1)
perror("Error sending to socket within FD_ISSET");
if (stdinbuffer[0] == '\n')
break;
}
}
close(sock);
return 0;
}
Instead of block reading stdin, you could use select on it too, which
would allow you to display incoming packets while the user types in
his new message. (Some management of the screen would be needed,
ncurses or at least manage raw input to be able to print back the
current user input).
[pjb@thalassa tmp]$ gcc -o a a.c
[pjb@thalassa tmp]$ ./a 127.0.0.1 25
220 thalassa.informatimago.com ESMTP Postfix
recv() in FD_ISSET: Resource temporarily unavailable
> HELO ici
> MAIL FROM: <pjb@xxxxxxxxxxxxxxxxx>
250 thalassa.informatimago.com
recv() in FD_ISSET: Resource temporarily unavailable
> RCPT TO: <pjb@xxxxxxxxxxxxxxxxx>
250 Ok
recv() in FD_ISSET: Resource temporarily unavailable
> DATA
250 Ok
recv() in FD_ISSET: Resource temporarily unavailable
> Subject: Test
354 End data with <CR><LF>.<CR><LF>
recv() in FD_ISSET: Resource temporarily unavailable
>
[pjb@thalassa tmp]$
--
__Pascal Bourguignon__ http://www.informatimago.com/
CAUTION: The mass of this product contains the energy equivalent of
85 million tons of TNT per net ounce of weight.
.
- Follow-Ups:
- Re: select(), sending and receiving data
- From: Maxim Yegorushkin
- Re: select(), sending and receiving data
- From: Markus Pitha
- Re: select(), sending and receiving data
- From: Markus Pitha
- Re: select(), sending and receiving data
- References:
- select(), sending and receiving data
- From: Markus Pitha
- select(), sending and receiving data
- Prev by Date: Re: Casting between 64bit and 32bit
- Next by Date: select(), sending and receiving data
- Previous by thread: select(), sending and receiving data
- Next by thread: Re: select(), sending and receiving data
- Index(es):
Relevant Pages
|