J
jessethepro
Hi all,
I have been racking my brain for days over the select() call. I use it
to monitor a socket and stdin. I run the program in two terminal
windows on localhost. The program is designed to allow two processes
to send and receive messages to each other. The problem is once one of
the processes sends its first message and the second process receives
it, the receiving processes is unable to send a message, but can
continue to receive. The code is the same for both processes I just
switch the the defined in and out ports. a copy of the program is
below and it compiles and runs on unix machines. The end result is a
p2p chat program I am designing. The program will run off of a
refferal system without a centralized server.
Thank you for any help
Jesse Johnson
//Code
/*
** dsoc.c IM program
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <time.h>
#include <sys/select.h>
#include <fcntl.h>
/* in order to run the program so the two processes can speak to each
other
** copy the program to a seperate file and switch the two ports below
*/
#define MYPORT_IN 20001 // the port users will be connecting to
#define MYPORT_OUT 20000 //port users will be writing to
#define MAXBUFLEN 100
int main(void){
int sockfd_in;
int sockfd_out;
struct sockaddr_in my_addr; // my address information
struct sockaddr_in their_addr; // connector's address information
int addr_len, numbytes;
char buf[MAXBUFLEN];
char string[100];
struct timeval tv;
int ready; //check if ready for input or output
fd_set read_fds;
fd_set write_fds;
tv.tv_sec = 0;
tv.tv_usec = 1000;
if ((sockfd_in = socket(AF_INET, SOCK_DGRAM, 0)) == -1){
perror("socket_in");
exit(1);
}
if ((sockfd_out = socket(AF_INET, SOCK_DGRAM, 0)) == -1){
perror("socket_out");
exit(1);
}
FD_ZERO(&read_fds);
FD_SET(sockfd_in, &read_fds);
FD_SET(STDIN_FILENO, &read_fds);
FD_SET(sockfd_out, &write_fds);
my_addr.sin_family = AF_INET; // host byte order
my_addr.sin_port = htons(MYPORT_IN); // short, network byte order
my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct
their_addr.sin_family = AF_INET; // host byte order
their_addr.sin_port = htons(MYPORT_OUT); // short, network byte order
inet_aton("127.0.0.1", &(their_addr.sin_addr));
memset(&(their_addr.sin_zero), '\0', 8); // zero the rest of the
struct
if (bind(sockfd_in, (struct sockaddr *)&my_addr, sizeof(struct
sockaddr)) == -1){
perror("bind");
exit(1);
}
addr_len = sizeof(struct sockaddr);
for(;
{
//block until stdin or sockfd_in have input
ready = select(sockfd_in + 1, &read_fds, NULL, NULL, NULL);
printf("here\n");
if(ready > 0){
if(FD_ISSET(sockfd_in, &read_fds)){
printf("in\n");
if ((numbytes=recvfrom(sockfd_in, buf, MAXBUFLEN-1, 0, (struct
sockaddr *)&their_addr, &addr_len)) == -1){
perror("recvfrom");
exit(1);
}
printf("got packet from %s\n",inet_ntoa(their_addr.sin_addr));
printf("packet is %d bytes long\n",numbytes);
buf[numbytes] = '\0';
printf("packet contains \"%s\"\n",buf);
//close(sockfd_in);
}
if(FD_ISSET(STDIN_FILENO, &read_fds)){
fgets(string, 100, stdin);
printf("out\n");
if ((numbytes=sendto(sockfd_out, string, strlen(string), 0, (struct
sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1){
perror("sendto");
exit(1);
}
printf("sent %d bytes to %s\n",
numbytes,inet_ntoa(their_addr.sin_addr));
//close(sockfd_out);
}
}
if(ready < 0){
perror("select");
}
}
return 0;
}
I have been racking my brain for days over the select() call. I use it
to monitor a socket and stdin. I run the program in two terminal
windows on localhost. The program is designed to allow two processes
to send and receive messages to each other. The problem is once one of
the processes sends its first message and the second process receives
it, the receiving processes is unable to send a message, but can
continue to receive. The code is the same for both processes I just
switch the the defined in and out ports. a copy of the program is
below and it compiles and runs on unix machines. The end result is a
p2p chat program I am designing. The program will run off of a
refferal system without a centralized server.
Thank you for any help
Jesse Johnson
//Code
/*
** dsoc.c IM program
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <time.h>
#include <sys/select.h>
#include <fcntl.h>
/* in order to run the program so the two processes can speak to each
other
** copy the program to a seperate file and switch the two ports below
*/
#define MYPORT_IN 20001 // the port users will be connecting to
#define MYPORT_OUT 20000 //port users will be writing to
#define MAXBUFLEN 100
int main(void){
int sockfd_in;
int sockfd_out;
struct sockaddr_in my_addr; // my address information
struct sockaddr_in their_addr; // connector's address information
int addr_len, numbytes;
char buf[MAXBUFLEN];
char string[100];
struct timeval tv;
int ready; //check if ready for input or output
fd_set read_fds;
fd_set write_fds;
tv.tv_sec = 0;
tv.tv_usec = 1000;
if ((sockfd_in = socket(AF_INET, SOCK_DGRAM, 0)) == -1){
perror("socket_in");
exit(1);
}
if ((sockfd_out = socket(AF_INET, SOCK_DGRAM, 0)) == -1){
perror("socket_out");
exit(1);
}
FD_ZERO(&read_fds);
FD_SET(sockfd_in, &read_fds);
FD_SET(STDIN_FILENO, &read_fds);
FD_SET(sockfd_out, &write_fds);
my_addr.sin_family = AF_INET; // host byte order
my_addr.sin_port = htons(MYPORT_IN); // short, network byte order
my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct
their_addr.sin_family = AF_INET; // host byte order
their_addr.sin_port = htons(MYPORT_OUT); // short, network byte order
inet_aton("127.0.0.1", &(their_addr.sin_addr));
memset(&(their_addr.sin_zero), '\0', 8); // zero the rest of the
struct
if (bind(sockfd_in, (struct sockaddr *)&my_addr, sizeof(struct
sockaddr)) == -1){
perror("bind");
exit(1);
}
addr_len = sizeof(struct sockaddr);
for(;
//block until stdin or sockfd_in have input
ready = select(sockfd_in + 1, &read_fds, NULL, NULL, NULL);
printf("here\n");
if(ready > 0){
if(FD_ISSET(sockfd_in, &read_fds)){
printf("in\n");
if ((numbytes=recvfrom(sockfd_in, buf, MAXBUFLEN-1, 0, (struct
sockaddr *)&their_addr, &addr_len)) == -1){
perror("recvfrom");
exit(1);
}
printf("got packet from %s\n",inet_ntoa(their_addr.sin_addr));
printf("packet is %d bytes long\n",numbytes);
buf[numbytes] = '\0';
printf("packet contains \"%s\"\n",buf);
//close(sockfd_in);
}
if(FD_ISSET(STDIN_FILENO, &read_fds)){
fgets(string, 100, stdin);
printf("out\n");
if ((numbytes=sendto(sockfd_out, string, strlen(string), 0, (struct
sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1){
perror("sendto");
exit(1);
}
printf("sent %d bytes to %s\n",
numbytes,inet_ntoa(their_addr.sin_addr));
//close(sockfd_out);
}
}
if(ready < 0){
perror("select");
}
}
return 0;
}