What is wrong with this code? I cannot get the port to connect to the socket at
ID: 3862752 • Letter: W
Question
What is wrong with this code? I cannot get the port to connect to the socket at all. When I enter a port number the client does nothing.
Instructions:
Implementing doServer(int listenFd) (10 Points):
doServer() should have a loop in which it waits for a client to connect to listenFd. When a client does, it should:
malloc() enough memory for 2 integers
put the file descriptor from accept() in one of those spaces
put the value of threadCount in the other space, and increment threadCount
Make a detached thread to handle this new client. I called my function handleClient(), but you may call yours whatever. Pass the address of your malloc()-ed array.
The loop should then go back for another accept().
void* handleClient(void* vPtr) (10 Points):
(Or whatever you call your function that runs a thread for the client.)The thread id and the file descriptor are passed, but they come in as a void* pointer.
Use another pointer to cast back to int*
Save the file descriptor and thread number in local vars
free() the memory
Print the thread number and do a loop like this:
It read()s a line of text from the client into buffer[], and parses the line into a command character, fileNum integer, and quote-delineated text[] string. (The fileNum and text[] may or may not be given, depending upon the value of command.)
Then do the following operations based upon the value of command. Except for QUIT_CMD_CHAR I strongly recommend using a different function for each!
When the function ends just have it do:
command == DIR_CMD_CHAR (15 Points):
Open the current directory (named "."). If an error occurs then just send STD_ERROR_MSG back to the client.
Copy as many entries that will fit into a buffer of length BUFFER_LEN. Be sure to put a separating ' ' after each entry.
Close the directory.
command == READ_CMD_CHAR (15 Points):
Open the file with the number fileNum. Get the name from the number with:
read() up to BUFFER_LEN into a buffer. Put a '' character at the end of the buffer.
Send that buffer to the client.
Close the file.
If an error occurs during any of this, then send STD_ERROR_MSG back to the client.
command == WRITE_CMD_CHAR (15 Points):
The opposite of READ_CMD_CHAR. fileNum and text have the file number and text respectively from the client. Save that text to the named file. If there is an error send then send STD_ERROR_MSG back to the client. If you succeeded then send STD_OKAY_MSG back to the client.
command == DELETE_CMD_CHAR (10 Points):
fileNum tells the file number of the file to delete. Using the unlink() command. If there is an error send then send STD_ERROR_MSGback to the client. If you succeeded then send STD_OKAY_MSG back to the client.
command == CALC_CMD_CHAR (15 Points):
fork() a child. If fork() fails then send STD_ERROR_MSG back to the client.
For the child, do the following:
Then run CALC_PROGNAME. If running that fails, then do:
For the parent wait() for the child. If the child crashed or did not return EXIT_SUCCESS then send STD_ERROR_MSG back to the client.
If the child did not crash and returned EXIT_SUCCESS, then read() the first BUFFER_LEN chars from the file named OUTPUT_FILENAME. If there is any more space left in your buffer, then read() from the file named ERROR_FILENAME into the same buffer so that it has BUFFER_LEN chars maximum.
close() both files.
Send your buffer back to the client.
command == QUIT_CMD_CHAR (10 Points):
Just send STD_BYE_MSG back to the client and set shouldContinue to 0 to quit the loop.
/*-------------------------------------------------------------------------*
*--- ---*
*--- mathServer.c ---*
*--- ---*
*--- This file defines a C program that gets file-sys commands ---*
*--- from client via a socket, executes those commands in their own ---*
*--- threads, and returns the corresponding output back to the ---*
*--- client. ---*
*--- ---*
*--- ---- ---- ---- ---- ---- ---- ---- ---- ---*
*--- ---*
*--- Version 1.0 2017 February 20 Joseph Phillips ---*
*--- ---*
*-------------------------------------------------------------------------*/
// Compile with:
// $ gcc mathServer.c -o mathServer -lpthread
//--- Header file inclusion ---//
#include "mathClientServer.h"
#include <errno.h> // For perror()
#include <pthread.h> // For pthread_create()
#include <string.h>
#include <sys/socket.h>//For socket()
#include <netinet/in.h>//For sockaddr_in and htons()
#include <signal.h>
#include <wait.h>
//--- Definition of constants: ---//
#define STD_OKAY_MSG "Okay"
#define STD_ERROR_MSG "Error doing operation"
#define STD_BYE_MSG "Good bye!"
#define THIS_PROGRAM_NAME "mathServer"
#define FILENAME_EXTENSION ".bc"
#define OUTPUT_FILENAME "out.txt"
#define ERROR_FILENAME "err.txt"
#define CALC_PROGNAME "/usr/bin/bc"
const int ERROR_FD = -1;
extern void* handleClient(void* vPtr);
extern int getServerFileDescriptor();
//--- Definition of functions: ---//
// PURPOSE: To run the server by 'accept()'-ing client requests from
// 'listenFd' and doing them.
void doServer (int listenFd)
{
/* Application validity check: */
/* Server clients: */
pthread_t threadId;
pthread_attr_t threadAttr;
int threadCount = 0;
int *iPtr;
/* YOUR CODE HERE: */
while(1)
{
/* Accept connection to client: */
int conffd = accept(listenFd, NULL, NULL);
/* Malloc memory for two integers: */
iPtr = (int *)calloc(2, sizeof(int));
/*Put file descriptor in the first space: */
iPtr[0] = listenFd; // or just listenFd not sure
/* put threadCount into the second space and increment: */
iPtr[1] = threadCount++;
/* Creates detached thread for handleClient and passes the address of iPtr */
pthread_attr_init(&threadAttr);
pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED);
pthread_create(&threadId, &threadAttr, handleClient, (void*)iPtr);
pthread_join(threadId, NULL);
pthread_attr_destroy(&threadAttr);
}
}
void* handleClient(void* vPtr)
{
/* Read command: */
char buffer[BUFFER_LEN];
char command;
int fileNum;
char text[BUFFER_LEN];
int shouldContinue = 1;
int threadNum;
int fd;
/* Cast void* vPtr back to an int */
int *iPtr = (int *)vPtr;
/* Assign file descriptor to a local value named 'fd'*/
fd = iPtr[0];
/* Assign thread number to local value named 'threadNum'*/
threadNum = iPtr[1];
free(iPtr);
while (shouldContinue)
{
memset(buffer,'',BUFFER_LEN);
memset(text ,'',BUFFER_LEN);
read(fd,buffer,BUFFER_LEN);
printf("Thread %d received: %s ",threadNum,buffer);
sscanf(buffer,"%c %d "%[^"]"",&command,&fileNum,text);
/* YOUR CODE HERE: */
if(command == DIR_CMD_CHAR)
{
/* 1. Open the current directory (named "."). If an error occurs then just send STD_ERROR_MSG back to the client: */
DIR* dirPtr = opendir(".");
struct dirent* entryPtr;
/* If error occurs send STD_ERROR_MSG to client: */
if ((dirPtr = opendir (".")) == NULL) {
{
write(fd, STD_ERROR_MSG, sizeof(STD_ERROR_MSG));
//return(EXIT_FAILURE);
}
/* Read as many entries that will fit into BUFFER_LEN
put as many entries into the buffer and send the buffer to client
d_name=entryPtr into the bufffer using strcat_s,
make sure buffer starts empty
buffer[0]=' ';
add new line char using stringcat " "
make sure do not go over buffer lengh */
if (dirPtr)
{
while ((entryPtr = readdir(dirPtr)) != NULL)
{
buffer[0]='';
int i;
int sizebuf = sizeof(buffer);
for (i = 0; i < sizebuf; i++)
{
strcat(buffer,entryPtr->d_name);
strcat(buffer," ");
}
}
}
/* 3. Close directory */
closedir(dirPtr);
}
else if (command == READ_CMD_CHAR)
{
/* 1. Open the file with the number fileNum. Get the name from the number with: */
fileNum = open(FILENAME_EXTENSION,O_RDONLY, 0); //Yeah, I think this is right, except with fileNum instead.
// changed fd to fileNum
/* If error occurs send STD_ERROR_MSG to client: */
if(fileNum < 0)
{
write(fileNum, STD_ERROR_MSG, sizeof(STD_ERROR_MSG)); // it looks like this is correct
exit(1);
}
/* 2. read() up to BUFFER_LEN into a buffer. Put a '' character at the end of the buffer: */
char fileName[BUFFER_LEN];
snprintf(fileName,BUFFER_LEN,"%d%s",fileNum,FILENAME_EXTENSION);
fileNum = read(fileNum, fileName, BUFFER_LEN-1);
fileName[fileNum] = '';
printf("Sending: %s", fileName);
write(fileNum, fileName, fileNum);
/* Close file: */
close(fileNum);
}
else if (command == WRITE_CMD_CHAR)
{
/* 1. Open the file with the number fileNum in write mode: */
fileNum = open(FILENAME_EXTENSION,O_WRONLY|O_CREAT|O_TRUNC,0660);
/* If error occurs send STD_ERROR_MSG to client: */
if(fileNum < 0)
{
write(fileNum, STD_ERROR_MSG, sizeof(STD_ERROR_MSG));
}
if (fileNum >0)
{
//fileNum and text have the file number and text respectively from the client.
//Save that text to the named file.
char fileName[BUFFER_LEN];
write (fileNum,fileName, sizeof(fileName));
//If you succeeded then send STD_OKAY_MSG back to the client
write(fileNum, STD_OKAY_MSG, sizeof(STD_OKAY_MSG));
}
/* Close file: */
close(fileNum);
}
else if (command == CALC_CMD_CHAR)
{
/* Create new fork named calcPid: */
int calcPid = fork();
/* If fork() failed: */
if(calcPid < 0)
{
write(fd, STD_ERROR_MSG, sizeof(STD_ERROR_MSG));
}
/* Child writes files: */
else if(calcPid == 0)
{
char fileName[BUFFER_LEN];
snprintf(fileName,BUFFER_LEN,"%d%s",fileNum,FILENAME_EXTENSION);
int inFd = open(fileName,O_RDONLY,0);
int outFd = open(OUTPUT_FILENAME,O_WRONLY|O_CREAT|O_TRUNC,0660);
int errFd = open(ERROR_FILENAME, O_WRONLY|O_CREAT|O_TRUNC,0660);
if ( (inFd < 0) || (outFd < 0) || (errFd < 0) )
{
fprintf(stderr,"Could not open one or more files ");
exit(EXIT_FAILURE);
}
close(0);
dup(inFd);
close(1);
dup(outFd);
close(2);
dup(errFd);
/* Run CALC_PROGNAME, if fails generate output: */
execl(CALC_PROGNAME,CALC_PROGNAME,fileName,NULL);
fprintf(stderr,"Could not execl %s ",CALC_PROGNAME);
exit(EXIT_FAILURE);
}
/* Parent reads files: */
else
{
/* Wait and check status of child process, if it crashes return STD_ERROR_MSG: */
int status;
pid_t return_pid = waitpid(calcPid, &status, WNOHANG);
if (return_pid == -1)
write(fd, STD_ERROR_MSG, sizeof(STD_ERROR_MSG));
/* If child process EXIT_SUCCESS, then run parent process: */
if (return_pid == calcPid)
{
char fileName[BUFFER_LEN];
snprintf(fileName,BUFFER_LEN,"%d%s",fileNum,FILENAME_EXTENSION);
int numBytes = 0;
int outFd = open(OUTPUT_FILENAME,O_RDONLY|O_CREAT,0660);
int errFd = open(ERROR_FILENAME, O_RDONLY|O_CREAT,0660);
if ( (outFd < 0) || (errFd < 0) )
{
fprintf(stderr,"Could not open one or more files ");
exit(EXIT_FAILURE);
}
while ( (numBytes = read(outFd, fileName, BUFFER_LEN)) > 0)
read(errFd, &fileName[numBytes], BUFFER_LEN);
close(0);
dup(outFd);
close(1);
dup(errFd);
}
}
}
else if (command == DELETE_CMD_CHAR)
{
if (fileNum > 0)
{
fileNum = unlink(buffer);
write(fd, STD_OKAY_MSG, sizeof(STD_OKAY_MSG));
}
else
write(fd, STD_ERROR_MSG, sizeof(STD_ERROR_MSG));
}
else if (command == QUIT_CMD_CHAR)
{
/* Send STD_BYE_MSG back to the client and set shouldContinue to 0 to quit the loop: */
write(fd, STD_BYE_MSG, sizeof(STD_BYE_MSG));
shouldContinue = 0;
}
}
}
printf("Thread %d quitting. ",threadNum);
return(NULL);
}
// PURPOSE: To decide a port number, either from the command line arguments
// 'argc' and 'argv[]', or by asking the user. Returns port number.
int getPortNum (int argc,
char* argv[]
)
{
// I. Application validity check:
// II. Get listening socket:
int portNum;
if (argc >= 2)
portNum = strtol(argv[1],NULL,0);
else
{
char buffer[BUFFER_LEN];
printf("Port number to monopolize? ");
fgets(buffer,BUFFER_LEN,stdin);
portNum = strtol(buffer,NULL,0);
}
// III. Finished:
return(portNum);
}
// PURPOSE: To attempt to create and return a file-descriptor for listening
// to the OS telling this server when a client process has connect()-ed
// to 'port'. Returns that file-descriptor, or 'ERROR_FD' on failure.
int getServerFileDescriptor
(int port
)
{
// I. Application validity check:
// II. Attempt to get socket file descriptor and bind it to 'port':
// II.A. Create a socket
int socketDescriptor = socket(AF_INET, // AF_INET domain
SOCK_STREAM, // Reliable TCP
0);
if (socketDescriptor < 0)
{
perror(THIS_PROGRAM_NAME);
return(ERROR_FD);
}
// II.B. Attempt to bind 'socketDescriptor' to 'port':
// II.B.1. We'll fill in this datastruct
struct sockaddr_in socketInfo;
// II.B.2. Fill socketInfo with 0's
memset(&socketInfo,'',sizeof(socketInfo));
// II.B.3. Use TCP/IP:
socketInfo.sin_family = AF_INET;
// II.B.4. Tell port in network endian with htons()
socketInfo.sin_port = htons(port);
// II.B.5. Allow machine to connect to this service
socketInfo.sin_addr.s_addr = INADDR_ANY;
// II.B.6. Try to bind socket with port and other specifications
int status = bind(socketDescriptor, // from socket()
(struct sockaddr*)&socketInfo,
sizeof(socketInfo)
);
if (status < 0)
{
perror(THIS_PROGRAM_NAME);
return(ERROR_FD);
}
// II.B.6. Set OS queue length:
listen(socketDescriptor,5);
// III. Finished:
return(socketDescriptor);
}
int main (int argc,
char* argv[]
)
{
// I. Application validity check:
// II. Do server:
int port = getPortNum(argc,argv);
int listenFd = getServerFileDescriptor(port);
int status = EXIT_FAILURE;
if (listenFd >= 0)
{
doServer(listenFd);
close(listenFd);
status = EXIT_SUCCESS;
}
// III. Finished:
return(status);
}
Explanation / Answer
// $ gcc mathServer.c -o mathServer -lpthread
//--- Header file inclusion ---//
#include "mathClientServer.h"
#include <errno.h> // For perror()
#include <pthread.h> // For pthread_create()
#include <string.h>
#include <sys/socket.h>//For socket()
#include <netinet/in.h>//For sockaddr_in and htons()
#include <signal.h>
#include <wait.h>
//--- Definition of constants: ---//
#define STD_OKAY_MSG "Okay"
#define STD_ERROR_MSG "Error doing operation"
#define STD_BYE_MSG "Good bye!"
#define THIS_PROGRAM_NAME "mathServer"
#define FILENAME_EXTENSION ".bc"
#define OUTPUT_FILENAME "out.txt"
#define ERROR_FILENAME "err.txt"
#define CALC_PROGNAME "/usr/bin/bc"
const int ERROR_FD = -1;
extern void* handleClient(void* vPtr);
extern int getServerFileDescriptor();
//--- Definition of functions: ---//
// PURPOSE: To run the server by 'accept()'-ing client requests from
// 'listenFd' and doing them.
void doServer (int listenFd)
{
/* Application validity check: */
/* Server clients: */
pthread_t threadId;
pthread_attr_t threadAttr;
int threadCount = 0;
int *iPtr;
/* YOUR CODE HERE: */
while(1)
{
/* Accept connection to client: */
int conffd = accept(listenFd, NULL, NULL);
/* Malloc memory for two integers: */
iPtr = (int *)calloc(2, sizeof(int));
/*Put file descriptor in the first space: */
iPtr[0] = listenFd; // or just listenFd not sure
/* put threadCount into the second space and increment: */
iPtr[1] = threadCount++;
/* Creates detached thread for handleClient and passes the address of iPtr */
pthread_attr_init(&threadAttr);
pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED);
pthread_create(&threadId, &threadAttr, handleClient, (void*)iPtr);
pthread_join(threadId, NULL);
pthread_attr_destroy(&threadAttr);
}
}
void* handleClient(void* vPtr)
{
/* Read command: */
char buffer[BUFFER_LEN];
char command;
int fileNum;
char text[BUFFER_LEN];
int shouldContinue = 1;
int threadNum;
int fd;
/* Cast void* vPtr back to an int */
int *iPtr = (int *)vPtr;
/* Assign file descriptor to a local value named 'fd'*/
fd = iPtr[0];
/* Assign thread number to local value named 'threadNum'*/
threadNum = iPtr[1];
free(iPtr);
while (shouldContinue)
{
memset(buffer,'',BUFFER_LEN);
memset(text ,'',BUFFER_LEN);
read(fd,buffer,BUFFER_LEN);
printf("Thread %d received: %s ",threadNum,buffer);
sscanf(buffer,"%c %d "%[^"]"",&command,&fileNum,text);
/* YOUR CODE HERE: */
if(command == DIR_CMD_CHAR)
{
/* 1. Open the current directory (named "."). If an error occurs then just send STD_ERROR_MSG back to the client: */
DIR* dirPtr = opendir(".");
struct dirent* entryPtr;
/* If error occurs send STD_ERROR_MSG to client: */
if ((dirPtr = opendir (".")) == NULL) {
{
write(fd, STD_ERROR_MSG, sizeof(STD_ERROR_MSG));
//return(EXIT_FAILURE);
}
/* Read as many entries that will fit into BUFFER_LEN
put as many entries into the buffer and send the buffer to client
d_name=entryPtr into the bufffer using strcat_s,
make sure buffer starts empty
buffer[0]=' ';
add new line char using stringcat " "
make sure do not go over buffer lengh */
if (dirPtr)
{
while ((entryPtr = readdir(dirPtr)) != NULL)
{
buffer[0]='';
int i;
int sizebuf = sizeof(buffer);
for (i = 0; i < sizebuf; i++)
{
strcat(buffer,entryPtr->d_name);
strcat(buffer," ");
}
}
}
/* 3. Close directory */
closedir(dirPtr);
}
else if (command == READ_CMD_CHAR)
{
/* 1. Open the file with the number fileNum. Get the name from the number with: */
fileNum = open(FILENAME_EXTENSION,O_RDONLY, 0); //Yeah, I think this is right, except with fileNum instead.
// changed fd to fileNum
/* If error occurs send STD_ERROR_MSG to client: */
if(fileNum < 0)
{
write(fileNum, STD_ERROR_MSG, sizeof(STD_ERROR_MSG)); // it looks like this is correct
exit(1);
}
/* 2. read() up to BUFFER_LEN into a buffer. Put a '' character at the end of the buffer: */
char fileName[BUFFER_LEN];
snprintf(fileName,BUFFER_LEN,"%d%s",fileNum,FILENAME_EXTENSION);
fileNum = read(fileNum, fileName, BUFFER_LEN-1);
fileName[fileNum] = '';
printf("Sending: %s", fileName);
write(fileNum, fileName, fileNum);
/* Close file: */
close(fileNum);
}
else if (command == WRITE_CMD_CHAR)
{
/* 1. Open the file with the number fileNum in write mode: */
fileNum = open(FILENAME_EXTENSION,O_WRONLY|O_CREAT|O_TRUNC,0660);
/* If error occurs send STD_ERROR_MSG to client: */
if(fileNum < 0)
{
write(fileNum, STD_ERROR_MSG, sizeof(STD_ERROR_MSG));
}
if (fileNum >0)
{
//fileNum and text have the file number and text respectively from the client.
//Save that text to the named file.
char fileName[BUFFER_LEN];
write (fileNum,fileName, sizeof(fileName));
//If you succeeded then send STD_OKAY_MSG back to the client
write(fileNum, STD_OKAY_MSG, sizeof(STD_OKAY_MSG));
}
/* Close file: */
close(fileNum);
}
else if (command == CALC_CMD_CHAR)
{
/* Create new fork named calcPid: */
int calcPid = fork();
/* If fork() failed: */
if(calcPid < 0)
{
write(fd, STD_ERROR_MSG, sizeof(STD_ERROR_MSG));
}
/* Child writes files: */
else if(calcPid == 0)
{
char fileName[BUFFER_LEN];
snprintf(fileName,BUFFER_LEN,"%d%s",fileNum,FILENAME_EXTENSION);
int inFd = open(fileName,O_RDONLY,0);
int outFd = open(OUTPUT_FILENAME,O_WRONLY|O_CREAT|O_TRUNC,0660);
int errFd = open(ERROR_FILENAME, O_WRONLY|O_CREAT|O_TRUNC,0660);
if ( (inFd < 0) || (outFd < 0) || (errFd < 0) )
{
fprintf(stderr,"Could not open one or more files ");
exit(EXIT_FAILURE);
}
close(0);
dup(inFd);
close(1);
dup(outFd);
close(2);
dup(errFd);
/* Run CALC_PROGNAME, if fails generate output: */
execl(CALC_PROGNAME,CALC_PROGNAME,fileName,NULL);
fprintf(stderr,"Could not execl %s ",CALC_PROGNAME);
exit(EXIT_FAILURE);
}
/* Parent reads files: */
else
{
/* Wait and check status of child process, if it crashes return STD_ERROR_MSG: */
int status;
pid_t return_pid = waitpid(calcPid, &status, WNOHANG);
if (return_pid == -1)
write(fd, STD_ERROR_MSG, sizeof(STD_ERROR_MSG));
/* If child process EXIT_SUCCESS, then run parent process: */
if (return_pid == calcPid)
{
char fileName[BUFFER_LEN];
snprintf(fileName,BUFFER_LEN,"%d%s",fileNum,FILENAME_EXTENSION);
int numBytes = 0;
int outFd = open(OUTPUT_FILENAME,O_RDONLY|O_CREAT,0660);
int errFd = open(ERROR_FILENAME, O_RDONLY|O_CREAT,0660);
if ( (outFd < 0) || (errFd < 0) )
{
fprintf(stderr,"Could not open one or more files ");
exit(EXIT_FAILURE);
}
while ( (numBytes = read(outFd, fileName, BUFFER_LEN)) > 0)
read(errFd, &fileName[numBytes], BUFFER_LEN);
close(0);
dup(outFd);
close(1);
dup(errFd);
}
}
}
else if (command == DELETE_CMD_CHAR)
{
if (fileNum > 0)
{
fileNum = unlink(buffer);
write(fd, STD_OKAY_MSG, sizeof(STD_OKAY_MSG));
}
else
write(fd, STD_ERROR_MSG, sizeof(STD_ERROR_MSG));
}
else if (command == QUIT_CMD_CHAR)
{
/* Send STD_BYE_MSG back to the client and set shouldContinue to 0 to quit the loop: */
write(fd, STD_BYE_MSG, sizeof(STD_BYE_MSG));
shouldContinue = 0;
}
}
}
printf("Thread %d quitting. ",threadNum);
return(NULL);
}
// PURPOSE: To decide a port number, either from the command line arguments
// 'argc' and 'argv[]', or by asking the user. Returns port number.
int getPortNum (int argc,
char* argv[]
)
{
// I. Application validity check:
// II. Get listening socket:
int portNum;
if (argc >= 2)
portNum = strtol(argv[1],NULL,0);
else
{
char buffer[BUFFER_LEN];
printf("Port number to monopolize? ");
fgets(buffer,BUFFER_LEN,stdin);
portNum = strtol(buffer,NULL,0);
}
// III. Finished:
return(portNum);
}
// PURPOSE: To attempt to create and return a file-descriptor for listening
// to the OS telling this server when a client process has connect()-ed
// to 'port'. Returns that file-descriptor, or 'ERROR_FD' on failure.
int getServerFileDescriptor
(int port
)
{
// I. Application validity check:
// II. Attempt to get socket file descriptor and bind it to 'port':
// II.A. Create a socket
int socketDescriptor = socket(AF_INET, // AF_INET domain
SOCK_STREAM, // Reliable TCP
0);
if (socketDescriptor < 0)
{
perror(THIS_PROGRAM_NAME);
return(ERROR_FD);
}
// II.B. Attempt to bind 'socketDescriptor' to 'port':
// II.B.1. We'll fill in this datastruct
struct sockaddr_in socketInfo;
// II.B.2. Fill socketInfo with 0's
memset(&socketInfo,'',sizeof(socketInfo));
// II.B.3. Use TCP/IP:
socketInfo.sin_family = AF_INET;
// II.B.4. Tell port in network endian with htons()
socketInfo.sin_port = htons(port);
// II.B.5. Allow machine to connect to this service
socketInfo.sin_addr.s_addr = INADDR_ANY;
// II.B.6. Try to bind socket with port and other specifications
int status = bind(socketDescriptor, // from socket()
(struct sockaddr*)&socketInfo,
sizeof(socketInfo)
);
if (status < 0)
{
perror(THIS_PROGRAM_NAME);
return(ERROR_FD);
}
// II.B.6. Set OS queue length:
listen(socketDescriptor,5);
// III. Finished:
return(socketDescriptor);
}
int main (int argc,
char* argv[]
)
{
// I. Application validity check:
// II. Do server:
int port = getPortNum(argc,argv);
int listenFd = getServerFileDescriptor(port);
int status = EXIT_FAILURE;
if (listenFd >= 0)
{
doServer(listenFd);
close(listenFd);
status = EXIT_SUCCESS;
}
// III. Finished:
return(status);
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.