c socket prog - select() problems - c

I'm new to network programming. I have to write a simple client/server program in C. The server will listen for a connection and the client will connect to the server, send a message, and receive an echo back from the client. We have to update this using select() to handle connections to multiple clients at the same time from the server process. I tried to implement select() on the client side like instructed,but I think I'm having an infinite loop on the client side in if(FD_ISSET(clientSockfd, &readfds)) part.
//client1.c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <resolv.h>
#include <arpa/inet.h>
const int BUF_SIZE = 512;
int main(int argc, char *argv[]) {
char buf[BUF_SIZE], buf2[BUF_SIZE];
char *msg;
struct sockaddr_in serverInfo;
int clientSockfd, errorCheck, readVal, numfd;
struct hostent *hostName;
fd_set readfds;
//make sure user entered correct arguments when starting client
if(argc != 3)
{
printf("error: must enter 'programName portNumber hostname'\n");
exit(errno);
}
//create socket and error check socket() call
clientSockfd=socket(AF_INET, SOCK_STREAM, 0);
if (clientSockfd == -1)
{
perror("error creating socket");
exit(errno);
}
//assign sockaddr_in info for RemoteAddr
bzero(&serverInfo, sizeof(serverInfo));
serverInfo.sin_family=AF_INET;
hostName=gethostbyname(argv[2]);
if(hostName == NULL)
{
herror("Error when calling gethostbyname()");
exit(errno);
}
memcpy((unsigned char *) &serverInfo.sin_addr, (unsigned char *)hostName->h_addr, hostName->h_length); //copy IP address to be used
serverInfo.sin_port=htons(atoi(argv[1])); //port number to be used, given in command line, must be converted to network byte order
//connect to server side
if(connect(clientSockfd, (struct sockaddr *)&serverInfo, sizeof(serverInfo)) == -1)
{
perror("error when connecting to server");
exit(errno);
}
while(1)
{
FD_ZERO(&readfds); //zero out set
FD_SET(fileno(stdin), &readfds);
FD_SET(clientSockfd, &readfds);
int maxfd = fileno(stdin);
if(maxfd < clientSockfd) maxfd = clientSockfd;
numfd = select(maxfd, &readfds, 0, 0, 0); //call select()
if(numfd > 0)
{
if(FD_ISSET(clientSockfd, &readfds))
{
//make sure buf is empty so it doesnt print extra chars
bzero(buf2, BUF_SIZE);
read(clientSockfd, buf2, BUF_SIZE);
}
if(FD_ISSET(fileno(stdin), &readfds))
{
bzero(buf, BUF_SIZE);
fgets(buf, BUF_SIZE-1, stdin);
printf("echo from server: %s\n", buf);
errorCheck = write(clientSockfd, buf, strlen(buf)+1);
if(errorCheck == -1)
{
perror("error writing");
}
}
}
else if(numfd == 0)
{
perror("Error using select()\n");
exit(0);
}
else
printf("no data\n");
}
//close connection to server
errorCheck = close(clientSockfd);
if(errorCheck == -1)
{
perror("Error closing connection.");
exit(errno);
}
return 0;
}
here is the server..
//server.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <resolv.h>
#include <arpa/inet.h>
#include <errno.h>
const int ASSIGNED_PORT = 17000;
const int BUF_SIZE = 512;
int main() {
int serverfd, clientfd;
struct sockaddr_in serverSock; //NOTE: a pointer to sockaddr_in can be cast to a pointer to
// a struct sockaddr - useful for connect()
char buf[BUF_SIZE];
int errorCheck, msgLength;
//create socket with error checking (-1 ret on error)
serverfd = socket(AF_INET, SOCK_STREAM, 0);
if(serverfd < 0 )
{
perror("socket failed.");
exit(errno);
}
//assign sockaddr_in info for server
bzero(&serverSock, sizeof(serverSock)); //set to all 0's
serverSock.sin_family = AF_INET;
serverSock.sin_addr.s_addr = htonl(INADDR_ANY);
serverSock.sin_port = htons(ASSIGNED_PORT);
//bind a name to the socket with error checking (0 ret on success)
errorCheck = bind(serverfd, (struct sockaddr*)&serverSock, sizeof(serverSock));
if(errorCheck < 0 )
{
perror("bind failed.");
exit(errno);
}
//listen for connections with error checking (0 ret on success)
errorCheck = listen(serverfd, 10);
if(errorCheck < 0 )
{
perror("listen failed.");
exit(errno);
}
printf("Listening for connections. Enter CNTRL-c to kill server.\n");
//create infinite loop to accept, read, write, and close connections with error hecking
while(1)
{
//accept the connection from the client
clientfd = accept(serverfd, 0, 0);
if(clientfd == -1)
{
perror("error accepting connection.");
exit(errno);
}
//read data from the client
bzero(buf, BUF_SIZE);
msgLength = read(clientfd, buf, BUF_SIZE-1);
if(msgLength == -1)
{
perror("error reading from client");
close(clientfd);
close(serverfd);
exit(errno);
}
if(buf[0] '\0')
{
printf("connection closing");
exit(0);
}
//print what the client sent
printf("Message from client: %s\n", buf);
//echo back what the client sent
errorCheck = write(clientfd, buf, strlen(buf)+1);
if(errorCheck == -1 )
{
perror("error writing to client");
exit(errno);
}
//close the connection
errorCheck = close(clientfd);
if(errorCheck == -1)
{
perror("error closing connection");
exit(errno);
}
}
errorCheck = close(serverfd);
if(errorCheck==-1)
{
perror("error closing server, exiting program now");
sleep(6);
exit(errno);
}
return 0;
}

I think the problem (or at least, a problem) in your client-side code is that you are passing the magic number 32 to select(). That's incorrect. What you should be passing is the maximum of all of the socket numbers, plus one. For example, something like this:
int maxfd = fileno(stdin);
if (maxfd < clientSockFD) maxfd = clientSockFD;
// further maximizations for other sockets would go here, if you had any other sockets...
numfd = select(maxfd+1, &readfds, 0, 0, 0);

You need to use select() on the server side to handle multiple clients, not on the client side.

Related

send() function is never called in server C

I have a server program here that checks the input sent from the client and returns a message back to the client wether the password is right or wrong .
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "Practical.h"
#include <unistd.h>
#include <sys/stat.h>
#define BUFSIZE 200
int main(int argc, char* argv[])
{
int numBytes = 0;
int MAXPENDING = 1;
char recvbuffer[BUFSIZE], sendbuffer[BUFSIZE];
char inp_user[BUFSIZE];
char inp_pass[BUFSIZE];
char pass[BUFSIZE] = "pass";
char user[BUFSIZE] = "admin";
int attemptsLeft = 3;
if (argc != 2)
DieWithUserMessage("Parameter(s)", "<Server Port>");
in_port_t servPort = atoi(argv[1]);
int servSock;
if ((servSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
DieWithSystemMessage("socket() failed");
struct sockaddr_in servAddr;
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servAddr.sin_port = htons(servPort);
if (bind(servSock, (struct sockaddr*) &servAddr, sizeof(servAddr)) < 0)
DieWithSystemMessage("bind() failed");
//accept incoming connection requests to the server socket
//MAXPENDING is the maximum number of connections
//that should be queued for this socket
if (listen(servSock, MAXPENDING) < 0)
DieWithSystemMessage("listen() failed");
for (;;)
{
//declare client address structure
struct sockaddr_in clntAddr;
socklen_t clntAddrLen = sizeof(clntAddr);
//return new file descriptor referring
//to the client socket , all read/write operations will be
//performed on this socket
int clntSock = accept(servSock, (struct sockaddr *) &clntAddr, &clntAddrLen);
//check if the client socket has not been created
if (clntSock < 0)
DieWithSystemMessage("accept() failed");
//retrieve the data sent by the client
while ((numBytes = recv(clntSock, recvbuffer, (BUFSIZE-1), 0)) > 0) {
recvbuffer[numBytes] = '\0';
fputs(recvbuffer, stdout);
// if(strstr(recvbuffer, "\r\n\r\n") > 0)
// break;
}
//check if data has not been received from the client
if (numBytes < 0)
DieWithSystemMessage("recv() failed");
//read username and password into the server's buffers
sscanf(recvbuffer, "%s %s", inp_user, inp_pass);
//check if the entered username and pasword is correct
if( (strcmp(user, inp_user) == 0)
&&
(strcmp(pass, inp_pass) == 0)
)
{
snprintf(sendbuffer, sizeof(sendbuffer), "%s", "PROCEED\r\n");
}
else //the credentials entered were incorrect
{
attemptsLeft--;
//check if user has no attempts left
if(attemptsLeft == 0) {
snprintf(sendbuffer, sizeof(sendbuffer), "%s", "DENIED\r\n" );
} else {
snprintf(sendbuffer, sizeof(sendbuffer), "%s", "NONO\r\n");
// "You have %d attempt(s) left", attemptsLeft);
}
}
printf("The send message contains %s \n\n", sendbuffer);
printf("brefore sending\n");
ssize_t numBytesSent = send(clntSock, sendbuffer, strlen(sendbuffer), 0);
printf("after sending\n");
if (numBytesSent < 0)
DieWithSystemMessage("send() failed");
printf("NOBYTES: %d", numBytes);
close(clntSock);
}
}
The message contains prints successfully meaning a message is created for the user however the send() function is never called and the client never receives this message. Anyone know why this would happen?

TCP server/client how to keep connections alive?

I wrote a simple TCP echo server to handle multiple clients. It uses select() to get multiple connections.
Server Code:
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
int create_listener(uint16_t port) {
int listen_fd;
struct sockaddr_in name;
listen_fd = socket(AF_INET, SOCK_STREAM, 0);
if (listen_fd < 0) {
perror ("socket");
exit(EXIT_FAILURE);
}
bzero(&name, sizeof(name));
name.sin_family = AF_INET;
name.sin_addr.s_addr = htonl(INADDR_ANY);
name.sin_port = htons(port);
if (bind(listen_fd, (struct sockaddr *) &name, sizeof(name)) < 0) {
perror ("bind");
exit(EXIT_FAILURE);
}
return listen_fd;
}
int read_from_client(int fd) {
char buffer[100];
int nbytes;
nbytes = read(fd, buffer, 100);
if (nbytes < 0) {
perror("read");
exit(EXIT_FAILURE);
}
else if (nbytes == 0) {
return -1;
}
else {
fprintf(stderr, "Server: got message: %s\n", buffer);
write(fd, buffer, strlen(buffer) + 1);
return 0;
}
}
int main(int argc, char *argv[]) {
int listen_fd;
uint16_t port = 22000;
fd_set active_fd_set, read_fd_set;
int i;
struct sockaddr_in servaddr;
/* Create the socket and set it up to accept connections. */
listen_fd = create_listener(port);
if (listen(listen_fd, 10) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
/* Initialize the set of active sockets. */
FD_ZERO(&active_fd_set);
FD_SET(listen_fd, &active_fd_set);
while (1) {
/* Block until input arrives on one or more active sockets. */
read_fd_set = active_fd_set;
if (select(FD_SETSIZE, &read_fd_set, NULL, NULL, 0) < 0) {
perror("select");
exit(EXIT_FAILURE);
}
/* Service all the sockets with input pending. */
for (i = 0; i < FD_SETSIZE; ++i) {
if (FD_ISSET(i, &read_fd_set)) {
if (i == listen_fd) {
/* Connection request on original socket. */
int new_fd;
new_fd = accept(listen_fd, (struct sockaddr *) NULL, NULL);
if (new_fd < 0) {
perror ("accept");
exit(EXIT_FAILURE);
}
FD_SET(new_fd, &active_fd_set);
}
else {
/* Data arriving on an already-connected socket. */
if (read_from_client(i) < 0) {
close(i);
FD_CLR(i, &active_fd_set);
}
}
}
}
}
return 0;
}
Client code:
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
int sockfd, n;
char sendline[100];
char recvline[100];
struct sockaddr_in servaddr;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(22000);
inet_pton(AF_INET, "127.0.0.1", &(servaddr.sin_addr));
connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
while (1) {
bzero(sendline, 100);
bzero(recvline, 100);
fgets(sendline, 100, stdin);
write(sockfd, sendline, strlen(sendline) + 1);
read(sockfd, recvline, 100);
printf("%s", recvline);
}
return 0;
}
The problem is when I run server in one terminal and run two clients in another two terminals. If I use Ctrl+C to terminate one client, the server automatically terminates. I'm wondering why the server acts this way. What I'm expecting is the server runs forever. When client 1 terminates, server should still has a live connection with client 2.
Looks like you're hitting the exit in read_from_client. In general, in a server that serves multiple clients, you probably don't want to exit when you have a failure with one of the client connections.

C echo server still echoes once after being terminated

I have written a simple echo server and a client in C.
Here is the server code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include "unp.h"
#define SERVER_PORT 10000
void start_echo_service(int connfd);
void SIGCHLD_handler(int signum);
int main()
{
int listenfd, connfd;
socklen_t len;
struct sockaddr_in server_addr, client_addr;
pid_t child_pid;
printf("***Starting the echo server***\n");
if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("Failed to create connection socket. Exiting...\n");
exit(0);
}
bzero(&server_addr, sizeof(struct sockaddr_in));
bzero(&client_addr, sizeof(struct sockaddr_in));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(SERVER_PORT);
if(bind(listenfd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0)
{
strerror(errno);
exit(0);
}
if(listen(listenfd, 1000) < 0)
{
strerror(errno);
exit(0);
}
/* Add the handler for SIGCHLD */
struct sigaction sigchld_action;
sigchld_action.sa_handler = SIGCHLD_handler;
sigemptyset(&sigchld_action.sa_mask);
sigchld_action.sa_flags = 0;
if(sigaction(SIGCHLD, &sigchld_action, NULL) < 0)
{
printf("Error while adding handler for SIGCHLD\n");
exit(0);
}
while(1)
{
len = sizeof(client_addr);
if((connfd = accept(listenfd, (struct sockaddr *) &client_addr, &len)) < 0)
{
if(errno == EINTR)
continue;
else
{
strerror(errno);
exit(0);
}
}
child_pid = fork();
if(child_pid < 0)
{
//some error occured
strerror(errno);
exit(0);
}
else if(child_pid == 0)
{
// child process
close(listenfd);
start_echo_service(connfd);
close(connfd);
exit(1);
}
close(connfd);
}
close(connfd);
return 1;
}
void SIGCHLD_handler(int signum)
{
pid_t pid;
if((pid = waitpid(-1, NULL, 0)) > 0)
printf("Harvested child (pid): %d\n", pid);
}
void start_echo_service(int connfd)
{
char buf[256];
int bytes_read;
while(1)
{
if((bytes_read = read(connfd, buf, sizeof(buf))) > 0)
{
writen(connfd, buf, bytes_read);
continue;
}
else if(bytes_read == 0)
break;
else
{
if(errno == EINTR)
continue;
else
{
printf("Read error\n");
break;
}
}
}
}
Here is the client code:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include "unp.h"
#define SERVER_PORT 10000
void start_echo_client(int connfd);
int main(int argc, char *argv[])
{
int connfd;
struct sockaddr_in server_addr;
if(argc != 2)
{
printf("Usage: echo_client <server-address>\n");
exit(-1);
}
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
inet_pton(AF_INET, argv[1], &(server_addr.sin_addr));
server_addr.sin_port = htons(SERVER_PORT);
if((connfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
strerror(errno);
exit(0);
}
if(connect(connfd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0)
{
strerror(errno);
exit(0);
}
start_echo_client(connfd);
return 1;
}
void start_echo_client(int connfd)
{
char buffer[256];
while(fgets(buffer, sizeof(buffer), stdin) != NULL)
{
writen(connfd, buffer, strlen(buffer));
readn(connfd, buffer, strlen(buffer));
printf("%s", buffer);
}
}
I start my server with ./echo_server on one shell.
I start my client with ./echo_client 127.0.0.1 on another shell. So far, so good.
On my client, I type a message, say hello. The server echoes it back. Now, I terminate my server with Ctrl+C. The client is still running. Now, I type another message on the client, say zzz. I still get an echo back and zzz is printed on the shell. On typing another message on the client, it terminates.
I guess it may have something to do with the server being in uninterruptible sleep when I terminate it, but I can't be sure.
Here is the link to unp.h and unp.c
start_echo_client prints buffer irrespective of the return from readn, isn't? Even if server closed, buffer would contain contents of what happened with writen ( You use same buffer for write and read). Hence i think, you assume there was an echo from server while it was not.
The test with tcpdump as well indicates that FIN does arrive with ctrl-c on the server terminal. Client tries write ignoring the peer closure for which RST is received.
Also, read didn't yield zero on FIN. I changed to recv then the closure was caught.
Return the number of bytes read in the readn function instead what is being currently done and if its zero, then don't print buffer.

How does an incoming connection stop select from waiting?

As in the example, select monitors the socket of the server that listens for an incoming connection. I used telnet to test the program. In the program, select is supposed to stop waiting when there is something to read from the listener socket. I guessed telnet may send a message to the server and tried to read it, but I got nothing. Actually, the program stopped accepting new connections when I tried to read the message from telnet. I commented out the message reading code. Can someone explain why select stops waiting when there is a new connection?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/time.h>
#include "../cus_header/cus_header.h"
#define PORT "30000" // the port users will be connecting to
#define MY_IP "127.0.0.1"
#define BACKLOG 10 // how many pending connections queue will hold
#define MAXLEN 1000
void *get_client_addr(struct sockaddr * sa){
if(sa->sa_family == AF_INET){
return &(((struct sockaddr_in *)(sa))->sin_addr);
}
return &(((struct sockaddr_in6 *)(sa))->sin6_addr);
}
int main(int argc, char *argv[]){
struct addrinfo hints, *res, *p;
struct sockaddr_storage client_addr;
int client_add_len;
char client_ip[INET6_ADDRSTRLEN];
int a;
int listener, new_fd;
int yes = 1;
socklen_t c_addr_size;
char msg [] = "Hello client\n"; // message to the client
char *msg_p;
int msg_len = strlen(msg);
// load data to struct addrinfo
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
//create socket
if((a = getaddrinfo(MY_IP, PORT, &hints, &res)) == -1){
fprintf(stderr, "Cannot get address info: %s", gai_strerror(a));
return 1;
}
p = res;
// loop through all the results
for(p = res; p != NULL; p = p->ai_next){
// create socket
if((listener = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1){
printf("cannot create the socket\n");
continue;
}
if(setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1){
error("cannot set reused for the socket");
}
// bind socket to port
if(bind(listener, p->ai_addr, p->ai_addrlen) == -1){
printf("cannot bind the socket\n");
continue;
}
break;
}
if(p == NULL){
error("Cannot create socket or bind the socket to the port");
}
freeaddrinfo(res);
// listen incoming connections
if(listen(listener, BACKLOG) == -1){
error("Cannot listen to connection");
}
// ready to communicate
puts("Waiting for connection ...");
fd_set master_set, copy_master_set;
int fd_max;
int client_fd[20]; // store all the new fd here
// accept connection and talk with clients
while(1){
FD_ZERO(&master_set);
FD_SET(listener, &master_set);
fd_max = listener;
copy_master_set = master_set;
if(select(fd_max + 1, &copy_master_set, NULL, NULL, NULL) == -1){
error("Select");
}
int i;
// set all the available client fd
for(i = 0;i <= fd_max; i++){
if(FD_ISSET(i, &copy_master_set)){
if(i == listener){
// got a new connection
client_add_len = sizeof client_addr;
if((new_fd = accept(listener, (struct sockaddr *)&client_addr, &client_add_len)) == -1){
error("New connection");
}
FD_SET(new_fd, &master_set);
if(new_fd > fd_max){
fd_max = new_fd;
}
printf("New connection from %s on socket %i\n",
inet_ntop(client_addr.ss_family, get_client_addr((struct sockaddr *)&client_addr), client_ip, INET6_ADDRSTRLEN),
new_fd);
/*
char buf[MAXLEN];
int b;
if((b=recv(listener, buf, MAXLEN, 0)) == -1){
error("read message");
}else if(b == 0){
printf("Message from client: %s", buf);
}
printf("Message from client: %s", buf);
*/
}else{
// handle clients
}
}
}
}
return 0;
}
From the man page for select:
DESCRIPTION
select() and pselect() allow a program to monitor multiple file
descriptors, waiting until one or more of the file descriptors
become "ready" for some class of I/O operation (e.g., input
possible). A file descriptor is considered ready if it is pos-
sible to perform the corresponding I/O operation (e.g.,
read(2)) without blocking.
In this case, the file descriptor becomes ready when the socket receives an incoming connection and it is possible to perform the corresponding I/O operation of accept(2).

Running a program from Server and connecting this to the same client

I am sending hello.c file from the client to the server. The server receives it and stores it as hello123.c. I am trying to compile this file and run it using the system() command.
In this hello.c / hello123.c, I am trying to connect back to the same client.
/* Server Program*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <signal.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <netdb.h>
#define PORT 20001
#define BACKLOG 5
#define LENGTH 512
int main ()
{
int sockfd;
int nsockfd;
int num;
int sin_size;
struct sockaddr_in addr_local; /* client addr */
struct sockaddr_in addr_remote; /* server addr */
char revbuf[LENGTH];
/* Get the Socket file descriptor */
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 )
{
fprintf(stderr, "ERROR: Failed to obtain Socket Descriptor. (errno = %d)\n", errno);
exit(1);
}
else
printf("[Server] Obtaining socket descriptor successfully.\n");
/* Fill the client socket address struct */
addr_local.sin_family = AF_INET; // Protocol Family
addr_local.sin_port = htons(PORT); // Port number
addr_local.sin_addr.s_addr = INADDR_ANY; // AutoFill local address
bzero(&(addr_local.sin_zero), 8); // Flush the rest of struct
/* Bind a special Port */
if( bind(sockfd, (struct sockaddr*)&addr_local, sizeof(struct sockaddr)) == -1 )
{
fprintf(stderr, "ERROR: Failed to bind Port. (errno = %d)\n", errno);
exit(1);
}
else
printf("[Server] Binded tcp port %d in addr 127.0.0.1 sucessfully.\n",PORT);
/* Listen remote connect/calling */
if(listen(sockfd,BACKLOG) == -1)
{
fprintf(stderr, "ERROR: Failed to listen Port. (errno = %d)\n", errno);
exit(1);
}
else
printf ("[Server] Listening the port %d successfully.\n", PORT);
int success = 0;
while(success == 0)
{
sin_size = sizeof(struct sockaddr_in);
/* Wait a connection, and obtain a new socket file despriptor for single connection */
if ((nsockfd = accept(sockfd, (struct sockaddr *)&addr_remote, &sin_size)) == -1)
{
fprintf(stderr, "ERROR: Obtaining new Socket Despcritor. (errno = %d)\n", errno);
exit(1);
}
else
printf("[Server] Server has got connected from %s.\n", inet_ntoa(addr_remote.sin_addr));
char buffer[256];
bzero(buffer,256);
int n = 0;
n = read(nsockfd, buffer, 255);
if (n < 0) error("ERROR reading from socket");
printf("msg: %s\n",buffer);
/*Receive File from Client */
char* fr_name = "hello123.c";
FILE *fr = fopen(fr_name, "a");
if(fr == NULL)
printf("File %s Cannot be opened file on server.\n", fr_name);
else
{
bzero(revbuf, LENGTH);
int fr_block_sz = 0;
while((fr_block_sz = recv(nsockfd, revbuf, LENGTH, 0)) > 0)
{
int write_sz = fwrite(revbuf, sizeof(char), fr_block_sz, fr);
if(write_sz < fr_block_sz)
{
error("File write failed on server.\n");
}
bzero(revbuf, LENGTH);
if (fr_block_sz == 0 || fr_block_sz != 512)
{
break;
}
}
if(fr_block_sz < 0)
{
if (errno == EAGAIN)
{
printf("recv() timed out.\n");
}
else
{
fprintf(stderr, "recv() failed due to errno = %d\n", errno);
exit(1);
}
}
printf("Ok received from client!\n");
fclose(fr);
}
system("gcc hello123.c -o hello123.out");
system("./hello123.out");
}
}
The following is the Client Program.
/* Client Program */
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <signal.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <netdb.h>
#define PORT1 20001
#define PORT2 20002
#define LENGTH 512
int main(int argc, char *argv[]){
int sockfd;
int nsockfd;
char revbuf[LENGTH];
struct sockaddr_in remote_addr;
struct sockaddr_in server;
struct sockaddr_in dest;
int status,socket_fd, client_fd,num;
socklen_t size;
char buffer[1024];
char *buff, ch;
/* Get the Socket file descriptor */
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
fprintf(stderr, "ERROR: Failed to obtain Socket Descriptor! (errno = %d)\n",errno);
exit(1);
}
/* Fill the socket address struct */
remote_addr.sin_family = AF_INET;
remote_addr.sin_port = htons(PORT1);
inet_pton(AF_INET, "127.0.0.1", &remote_addr.sin_addr);
bzero(&(remote_addr.sin_zero), 8);
/* Try to connect the remote */
if (connect(sockfd, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr)) == -1)
{
fprintf(stderr, "ERROR: Failed to connect to the host! (errno = %d)\n",errno);
exit(1);
}
else
printf("[Client] Connected to server at port %d...ok!\n", PORT1);
/* Send File to Server */
//if(!fork())
//{
char* fs_name = "hello.c";
char sdbuf[LENGTH];
// char buffer[256];
int n;
fgets(buffer,255,stdin);
// bzero(buffer,256);
n = write(sockfd,buffer, strlen(buffer));
if(n<0) printf("Error: sending filename");
printf("[Client] Sending %s to the Server... ", fs_name);
FILE *fs = fopen(fs_name, "r");
if(fs == NULL)
{
printf("ERROR: File %s not found.\n", fs_name);
exit(1);
}
bzero(sdbuf, LENGTH);
int fs_block_sz;
while((fs_block_sz = fread(sdbuf, sizeof(char), LENGTH, fs)) > 0)
{
if(send(sockfd, sdbuf, fs_block_sz, 0) < 0)
{
fprintf(stderr, "ERROR: Failed to send file %s. (errno = %d)\n", fs_name, errno);
break;
}
bzero(sdbuf, LENGTH);
}
printf("Ok File %s from Client was Sent!\n", fs_name);
//}
//while(1) {
remote_addr.sin_family = AF_INET;
remote_addr.sin_port = htons(PORT2);
inet_pton(AF_INET, "127.0.0.1", &remote_addr.sin_addr);
bzero(&(remote_addr.sin_zero), 8);
size = sizeof(struct sockaddr_in);
if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size))==-1 )
{
perror("accept");
exit(1);
}
printf("Server got connection from client %s\n", inet_ntoa(dest.sin_addr));
while(1) {
if ((num = recv(client_fd, buffer, 1024,0))== -1) {
perror("recv");
exit(1);
}
else if (num == 0) {
printf("Connection closed\n");
//So I can now wait for another client
break;
}
buffer[num] = '\0';
printf("Server:Msg Received %s\n", buffer);
}//End of Inner While...
//Close Connection Socket
close(client_fd);
close (sockfd);
printf("[Client] Connection lost.\n");
return (0);
}
The following is the Hello.c
/* Hello.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 20002
#define MAXSIZE 1024
#define SA struct sockaddr
int main(int argc, char *argv[])
{
int sockfd,connfd;
struct sockaddr_in server_info;
struct hostent *he;
int socket_fd,client_fd,num;
char buffer[1024];
char i;
char buff[1024];
struct sockaddr_in servaddr,cli;
sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd==-1)
{
printf("Hello:socket creation failed...\n");
exit(0);
}
else
printf("Hello:Socket successfully created..\n");
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_addr.s_addr=inet_addr("127.0.0.1");
servaddr.sin_port=htons(PORT);
if(connect(sockfd,(SA *)&servaddr,sizeof(servaddr))!=0)
{
printf("Hello:connection with the server failed...\n");
exit(0);
}
else
printf("Hello:connected to the server..\n");
printf("\n Hello:Choose between 1 and 2\n");
printf("Hello:Enter Data for Server:\n");
fgets(buffer,MAXSIZE,stdin);
if ((send(socket_fd,buffer, strlen(buffer),0))== -1) {
fprintf(stderr, "Hello:Failure Sending Message\n");
close(socket_fd);
exit(1);
}
else {
printf("Hello:Client:Message being sent: %c\n",i);
close(socket_fd);
}
}
When I run the program, the file transfer is happening successfully. But the Hello.c is not getting connected to the client.
This is my output
Server Side:
$ ./server24.out
[Server] Obtaining socket descriptor successfully.
[Server] Binded tcp port 20001 in addr 127.0.0.1 sucessfully.
[Server] Listening the port 20001 successfully.
[Server] Server has got connected from 127.0.0.1.
msg:
Ok received from client!
Hello:Socket successfully created..
Hello:connection with the server failed...
Client Side:
$ ./client24.out
[Client] Connected to server at port 20001...ok!
[Client] Sending hello.c to the Server. Ok File hello.c from Client was Sent
accept: Socket operation on non-socket
I guess this is some address problem. But I am not able to figure out.
Please help.
Thanks in advance.
So your Client Program begin to act as a server but you haven't created the necessary socket to accept a connection there. socket_fd have been used uninitialized from socket()
Following need to be added updated after //while(1) { in Client
//while(1) {
/* Get the Socket file descriptor */
if ((socket_fd= socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
fprintf(stderr, "ERROR: Failed to obtain Socket Descriptor! (errno = %d)\n",errno);
exit(1);
}
/* Fill the socket address struct */
remote_addr.sin_family = AF_INET;
remote_addr.sin_port = htons(PORT2);
inet_pton(AF_INET, "127.0.0.1", &remote_addr.sin_addr);
bzero(&(remote_addr.sin_zero), 8);
if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size))==-1 )
{
perror("accept");
exit(1);
}

Resources