M
Marcia Hon
Hi,
I am trying to use the select() socket programming command to select between
stdin and a connection. Currently, I have a listening stream and stdin that
I insert into the fd_set. The problem is that when I recognize FD_ISSET from
stdin, I am stuck there. The loop does not return me to select() between
stdin and listening socket. Similarly, when I accept a client, the loop does
not return me to select between stdin and listeing socket. I don't know what
to do. I want to be able to select continuously between stdin and the
listening port after I have either accepted from a port or from stdin.
I have pasted the codes that I am using for the listening to port and stdin
and the code for the client.
Please help.
Thank you,
Marcia Hon
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define max(a, b) ((a) > (b) ? a: b)
int flushToEndOfLine();
int main(int argc, char *argv[])
{
fd_set master;
struct sockaddr_in myaddr;
struct sockaddr_in remoteaddr;
int fdmax;
int listenerSocket;
int newfd;
char buf[256];
int yes = 1;
int addrlen;
int i, j;
if(argc != 2)
{
fprintf(stderr, "Usage: %s <listen_port>\n", argv[0]);
exit(1);
}
FD_ZERO(&master); //clear master set
// get listenerSocket
if((listenerSocket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
// lose socket already in use error message
if(setsockopt(listenerSocket, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
// bind
myaddr.sin_family = AF_INET;
myaddr.sin_addr.s_addr = INADDR_ANY;
myaddr.sin_port = htons(atoi(argv[1]));
memset(&(myaddr.sin_zero), '\0', 8);
if(bind(listenerSocket, (struct sockaddr *) &myaddr, sizeof(myaddr)) == -1)
{
perror("bind");
exit(1);
}
// listen
if(listen(listenerSocket, 5) == -1) {
perror("listen");
exit(1);
}
FD_SET(listenerSocket, &master);
FD_SET(0, &master);
fdmax = max(listenerSocket, 0);
while(1){
printf("select\n");
if(select(fdmax+1, &master, NULL, NULL, NULL) == -1){
perror("select");
exit(1);
}
if(FD_ISSET(listenerSocket, &master)){
addrlen = sizeof(remoteaddr);
if((newfd = accept(listenerSocket, (struct
sockaddr *)&remoteaddr, &addrlen)) == -1) {
perror("accept");
}
printf("new connection from client\n");
close(newfd);
}
else
{
if(FD_ISSET(0, &master))
{
printf("user entered data \n");
flushToEndOfLine();
}
}
}
return 0;
}
int flushToEndOfLine()
{
int c;
while ( (c=getchar()) != EOF && c != '\n' );
return;
}
client:
//WHAT IF SHORT IS NOT 2 BYTES?!?!?!?
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#define FILE_TBYTES 4 //bytes at the beginning of file that specify how many
bytes are in this block being sent
#define MAX_BYTES 1000 //breaks up file into this many bytes and sends this
many bytes at a time
#define MAX_BSEND_RETRY 3 //how many times to retry sending a block of
MAX_BYTES before fail
#define DEBUG
//prototypes
int establish_connection (const char * name, unsigned short port);
int send_stream (int sockfd, const char * data, int len);
unsigned long getFileSize(char *fileName);
//check ip or dns
int main(int argc, char *argv[])
{
FILE *fp;
int j; //loop counters
short int i; //this better be 2 bytes
char * buffer;
unsigned long *tmp;
unsigned short port;
int sockfd;
unsigned long fileSize;
if ((buffer = (char *) malloc (MAX_BYTES)) == NULL)
{
fprintf(stderr, "Not enough memory for a file input buffer of %d\n",
MAX_BYTES);
exit(1);
}
//Check if 3 arguments passed
if (argc !=4)
{
fprintf(stderr, "Usage: %s <ip> <port> <file>\n", argv[0]);
exit(1);
}
//no check!
port = atoi(argv[2]);
#ifdef DEFINE
printf("Arguments Passed:\n");
printf("IP: %s\n", argv[1]);
printf("PORT: %d\n", port);
printf("FILE: %s\n", argv[3]);
printf("\n");
#endif
//open file
if ((fp = fopen(argv[3],"r")) == NULL)
{
fprintf(stderr, "Error: Could not open %s\n", argv[3]);
exit(1);
}
if ((sockfd = establish_connection (argv[1], port)) == -1)
{
fprintf(stderr, "Error establishing connection\n");
fclose(fp);
exit(1);
}
//buffer = "Hello World";
//send_stream(sockfd, buffer, 11);
//send file size
fileSize = getFileSize(argv[3]);
tmp = (unsigned long *) &buffer[0];
*tmp = (unsigned long) htonl(fileSize);
send_stream(sockfd, buffer, 4);
printf("File Size: %d\n", fileSize);
while (!feof(fp))
{
//read some bytes
for (i = 0; i<MAX_BYTES; i++)
{
buffer = fgetc(fp);
if (feof(fp)) //end of file true
break;
}
//echo bytes to screen
for (j=0; j<i; j++)
{
//put send function here
//printf("%c", buffer[j]);
}
if (!send_stream(sockfd, buffer, i))
{
fprintf(stderr, "Error sending a block\n");
exit(1);
}
}
//close file
fclose(fp);
close(sockfd);
return 0; //exited succesfully
}
//pass name of the host and port number only!
//-1 fail, sockfd success
int establish_connection (const char * name, unsigned short port)
{
struct sockaddr_in their_addr;
int sockfd;
int r; //returned from functions
struct hostent * h;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
//set up the structure
their_addr.sin_family = AF_INET;
their_addr.sin_port = htons(port); // short, network byte order
memset(&(their_addr.sin_zero), '\0', 8); // zero the rest of the struct
h=gethostbyname(name);
if (h == NULL)
return -1;
//1. make *h_addr_list[0] be a in_addr *
//2. dereference this pointer and assign it to their_addr.sin_addr
their_addr.sin_addr = *((struct in_addr *)h->h_addr);
printf("IP Address : %s\n", inet_ntoa(*((struct in_addr *)h->h_addr)));
printf("IP Address : %s\n", inet_ntoa(their_addr.sin_addr));
printf("Port: %d \n", ntohs(their_addr.sin_port));
if((connect(sockfd, (struct sockaddr *) &their_addr, sizeof(struct
sockaddr))) == -1)
return -1;
return sockfd;
}
//sends data
//connect may return that it sent less, this function sends the rest
//return 0 on fail, 1 on success
int send_stream (int sockfd, const char * data, int len)
{
int bytes_sent, newlen;
const void * newdata;
bytes_sent = send(sockfd, data, len,0);
if (bytes_sent < 0)
return 0;
while (bytes_sent < len - 1)
{
//if we sent 10 bytes, we sent bytes 0...9
//need to send byte 10...
newdata = &data[bytes_sent];
bytes_sent = send(sockfd, newdata, len - bytes_sent, 0);
if (bytes_sent < 0)
return 0;
}
return 1;
}
unsigned long getFileSize(char *fileName)
{
unsigned long fileSize;
FILE *f=fopen(fileName, "rb");
if(f==NULL)
{
fprintf(stderr, "Cannot open file.\n");
exit(EXIT_FAILURE);
}
else
{
if(fseek(f, 0, SEEK_END)!=0)
{
fprintf(stderr, "Cannot use file.\n");
exit(EXIT_FAILURE);
}
fileSize=ftell(f);
}
if(fclose(f)!=0)
{
fprintf(stderr, "Cannot close file.\n");
exit(EXIT_FAILURE);
}
return fileSize;
}
I am trying to use the select() socket programming command to select between
stdin and a connection. Currently, I have a listening stream and stdin that
I insert into the fd_set. The problem is that when I recognize FD_ISSET from
stdin, I am stuck there. The loop does not return me to select() between
stdin and listening socket. Similarly, when I accept a client, the loop does
not return me to select between stdin and listeing socket. I don't know what
to do. I want to be able to select continuously between stdin and the
listening port after I have either accepted from a port or from stdin.
I have pasted the codes that I am using for the listening to port and stdin
and the code for the client.
Please help.
Thank you,
Marcia Hon
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define max(a, b) ((a) > (b) ? a: b)
int flushToEndOfLine();
int main(int argc, char *argv[])
{
fd_set master;
struct sockaddr_in myaddr;
struct sockaddr_in remoteaddr;
int fdmax;
int listenerSocket;
int newfd;
char buf[256];
int yes = 1;
int addrlen;
int i, j;
if(argc != 2)
{
fprintf(stderr, "Usage: %s <listen_port>\n", argv[0]);
exit(1);
}
FD_ZERO(&master); //clear master set
// get listenerSocket
if((listenerSocket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
// lose socket already in use error message
if(setsockopt(listenerSocket, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
// bind
myaddr.sin_family = AF_INET;
myaddr.sin_addr.s_addr = INADDR_ANY;
myaddr.sin_port = htons(atoi(argv[1]));
memset(&(myaddr.sin_zero), '\0', 8);
if(bind(listenerSocket, (struct sockaddr *) &myaddr, sizeof(myaddr)) == -1)
{
perror("bind");
exit(1);
}
// listen
if(listen(listenerSocket, 5) == -1) {
perror("listen");
exit(1);
}
FD_SET(listenerSocket, &master);
FD_SET(0, &master);
fdmax = max(listenerSocket, 0);
while(1){
printf("select\n");
if(select(fdmax+1, &master, NULL, NULL, NULL) == -1){
perror("select");
exit(1);
}
if(FD_ISSET(listenerSocket, &master)){
addrlen = sizeof(remoteaddr);
if((newfd = accept(listenerSocket, (struct
sockaddr *)&remoteaddr, &addrlen)) == -1) {
perror("accept");
}
printf("new connection from client\n");
close(newfd);
}
else
{
if(FD_ISSET(0, &master))
{
printf("user entered data \n");
flushToEndOfLine();
}
}
}
return 0;
}
int flushToEndOfLine()
{
int c;
while ( (c=getchar()) != EOF && c != '\n' );
return;
}
client:
//WHAT IF SHORT IS NOT 2 BYTES?!?!?!?
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#define FILE_TBYTES 4 //bytes at the beginning of file that specify how many
bytes are in this block being sent
#define MAX_BYTES 1000 //breaks up file into this many bytes and sends this
many bytes at a time
#define MAX_BSEND_RETRY 3 //how many times to retry sending a block of
MAX_BYTES before fail
#define DEBUG
//prototypes
int establish_connection (const char * name, unsigned short port);
int send_stream (int sockfd, const char * data, int len);
unsigned long getFileSize(char *fileName);
//check ip or dns
int main(int argc, char *argv[])
{
FILE *fp;
int j; //loop counters
short int i; //this better be 2 bytes
char * buffer;
unsigned long *tmp;
unsigned short port;
int sockfd;
unsigned long fileSize;
if ((buffer = (char *) malloc (MAX_BYTES)) == NULL)
{
fprintf(stderr, "Not enough memory for a file input buffer of %d\n",
MAX_BYTES);
exit(1);
}
//Check if 3 arguments passed
if (argc !=4)
{
fprintf(stderr, "Usage: %s <ip> <port> <file>\n", argv[0]);
exit(1);
}
//no check!
port = atoi(argv[2]);
#ifdef DEFINE
printf("Arguments Passed:\n");
printf("IP: %s\n", argv[1]);
printf("PORT: %d\n", port);
printf("FILE: %s\n", argv[3]);
printf("\n");
#endif
//open file
if ((fp = fopen(argv[3],"r")) == NULL)
{
fprintf(stderr, "Error: Could not open %s\n", argv[3]);
exit(1);
}
if ((sockfd = establish_connection (argv[1], port)) == -1)
{
fprintf(stderr, "Error establishing connection\n");
fclose(fp);
exit(1);
}
//buffer = "Hello World";
//send_stream(sockfd, buffer, 11);
//send file size
fileSize = getFileSize(argv[3]);
tmp = (unsigned long *) &buffer[0];
*tmp = (unsigned long) htonl(fileSize);
send_stream(sockfd, buffer, 4);
printf("File Size: %d\n", fileSize);
while (!feof(fp))
{
//read some bytes
for (i = 0; i<MAX_BYTES; i++)
{
buffer = fgetc(fp);
if (feof(fp)) //end of file true
break;
}
//echo bytes to screen
for (j=0; j<i; j++)
{
//put send function here
//printf("%c", buffer[j]);
}
if (!send_stream(sockfd, buffer, i))
{
fprintf(stderr, "Error sending a block\n");
exit(1);
}
}
//close file
fclose(fp);
close(sockfd);
return 0; //exited succesfully
}
//pass name of the host and port number only!
//-1 fail, sockfd success
int establish_connection (const char * name, unsigned short port)
{
struct sockaddr_in their_addr;
int sockfd;
int r; //returned from functions
struct hostent * h;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
//set up the structure
their_addr.sin_family = AF_INET;
their_addr.sin_port = htons(port); // short, network byte order
memset(&(their_addr.sin_zero), '\0', 8); // zero the rest of the struct
h=gethostbyname(name);
if (h == NULL)
return -1;
//1. make *h_addr_list[0] be a in_addr *
//2. dereference this pointer and assign it to their_addr.sin_addr
their_addr.sin_addr = *((struct in_addr *)h->h_addr);
printf("IP Address : %s\n", inet_ntoa(*((struct in_addr *)h->h_addr)));
printf("IP Address : %s\n", inet_ntoa(their_addr.sin_addr));
printf("Port: %d \n", ntohs(their_addr.sin_port));
if((connect(sockfd, (struct sockaddr *) &their_addr, sizeof(struct
sockaddr))) == -1)
return -1;
return sockfd;
}
//sends data
//connect may return that it sent less, this function sends the rest
//return 0 on fail, 1 on success
int send_stream (int sockfd, const char * data, int len)
{
int bytes_sent, newlen;
const void * newdata;
bytes_sent = send(sockfd, data, len,0);
if (bytes_sent < 0)
return 0;
while (bytes_sent < len - 1)
{
//if we sent 10 bytes, we sent bytes 0...9
//need to send byte 10...
newdata = &data[bytes_sent];
bytes_sent = send(sockfd, newdata, len - bytes_sent, 0);
if (bytes_sent < 0)
return 0;
}
return 1;
}
unsigned long getFileSize(char *fileName)
{
unsigned long fileSize;
FILE *f=fopen(fileName, "rb");
if(f==NULL)
{
fprintf(stderr, "Cannot open file.\n");
exit(EXIT_FAILURE);
}
else
{
if(fseek(f, 0, SEEK_END)!=0)
{
fprintf(stderr, "Cannot use file.\n");
exit(EXIT_FAILURE);
}
fileSize=ftell(f);
}
if(fclose(f)!=0)
{
fprintf(stderr, "Cannot close file.\n");
exit(EXIT_FAILURE);
}
return fileSize;
}