Re: select(), sending and receiving data



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.
.



Relevant Pages

  • Re: What doesnt lend itself to OO?
    ... >> proxy and instructs the server to constuct the real object. ... rather than client code. ... If 'clock' is instantiated in the server, ... > for the server interface at the OOA level. ...
    (comp.object)
  • This is going straight to the pool room
    ... or not the client has privilege to do what they're trying to do, ... The server environment is this: ... 3GL User action Routines that Tier3 will execute on your behalf during the ... Routine Name: USER_INIT ...
    (comp.os.vms)
  • [Full-Disclosure] R: Full-Disclosure Digest, Vol 3, Issue 42
    ... Full-Disclosure Digest, Vol 3, Issue 42 ... SD Server 4.0.70 Directory Traversal Bug ... Arkeia Network Backup Client Remote Access ...
    (Full-Disclosure)
  • Re: What doesnt lend itself to OO?
    ... > rather than client code. ... no way to do that without also touching the object with clock semantics ... will not encapsulate both clock semantics and network semantics. ... The server can do whatever it wants ...
    (comp.object)
  • RE: Fax monitor incoming + outgoing calls?
    ... problem between the client computer and the SBS server. ... Client is using the internal IP address of the SBS server as the ... To the folder redirection GPO issue: ...
    (microsoft.public.windows.server.sbs)