Socket sample diagram:
Resource:
http://www.tutorialspoint.com/unix_sockets/socket_core_functions.htm
To know basics of the socket go below:
http://www.tutorialspoint.com/unix_sockets/what_is_socket.htm
To know basic API's syntax in socket plz go here:
http://www.tutorialspoint.com/unix_sockets/socket_quick_guide.htm
SIMPLE ITERATIVE SERVER CODE:
* BLOCKING when do accepting for the connection
Server code 1:
Client code 1:
Resource: http://www.thegeekstuff.com/2011/12/c-socket-programming/
Server Code 2:
SIMPLE CONCURRENT SERVER CODE:
* BLOCKING when do accepting for the connection
* forking child process for each new connection after accepting the connection
Server code 1:
use above client code 2
practical example: https://www.scottklement.com/rpg/socktut/nonblocking.html
* The select system call is similar to the poll facility (examining the status of file descriptors of open input/output channels)
* there is no need for forked child process for handle each connection
* With select(), instead of having a process for each request, there is usually only one process that "multi-plexes" all requests, servicing each request as much as it can.
*
Advantage:
*main advantage of using select() is that your server will only require a single process to handle all requests.
*Thus, your server will not need shared memory or synchronization primitives for different 'tasks' to communicate.
Very basic code
Purpose of select:
http://stackoverflow.com/questions/14544621/why-is-select-used-in-linux
Resource:
http://www.tutorialspoint.com/unix_sockets/socket_core_functions.htm
To know basics of the socket go below:
http://www.tutorialspoint.com/unix_sockets/what_is_socket.htm
To know basic API's syntax in socket plz go here:
http://www.tutorialspoint.com/unix_sockets/socket_quick_guide.htm
SIMPLE ITERATIVE SERVER CODE:
* BLOCKING when do accepting for the connection
Server code 1:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
int main(int argc, char *argv[])
{
int listenfd = 0, connfd = 0;
struct sockaddr_in serv_addr;
char sendBuff[1025];
time_t ticks;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
memset(sendBuff, '0', sizeof(sendBuff));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(5000);
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
listen(listenfd, 10);
while(1)
{
connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
/* processing start here for accepted connection */.
ticks = time(NULL);
snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n", ctime(&ticks));
write(connfd, sendBuff, strlen(sendBuff));
/* processing finished here for accepted connection */.
/* so above part can be put in the fork for concurrent server */
close(connfd);
sleep(1);
}
}
INADDR_ANY explanation:
* INADDR_ANY is used when you don't need to bind a socket to a specific IP. When you use this value as the address when calling bind(), the socket accepts connections to all the IPs of the machine.
* This allowed your program to work without knowing the IP address of the machine it was running on, or, in the case of a machine with multiple network interfaces, it allowed your server to receive packets destined to any of the interfaces.
* If you wish to bind your socket to localhost only, the syntax would be
my_sockaddress.sin_addr.s_addr = inet_addr("127.0.0.1");, then call bind(my_socket, (SOCKADDR *) &my_sockaddr, ...)* Example: . For example, suppose that a host has interfaces 0, 1 and 2. If a UDP socket on this host is bound using INADDR_ANY and udp port 8000, then the socket will receive all packets for port 8000 that arrive on interfaces 0, 1, or 2. If a second socket attempts to Bind to port 8000 on interface 1, the Bind will fail since the first socket already ``owns'' that port/interface.
Ref: https://www.cs.cmu.edu/~srini/15-441/F01.full/www/assignments/P2/htmlsim_split/node18.html
https://stackoverflow.com/questions/16508685/understanding-inaddr-any-for-socket-programming-cClient code 1:
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
int sockfd = 0, n = 0;
char recvBuff[1024];
struct sockaddr_in serv_addr;
if(argc != 2)
{
printf("\n Usage: %s <ip of server> \n",argv[0]);
return 1;
}
memset(recvBuff, '0',sizeof(recvBuff));
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Error : Could not create socket \n");
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(5000);
if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0)
{
printf("\n inet_pton error occured\n");
return 1;
}
if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\n Error : Connect Failed \n");
return 1;
}
while ( (n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0)
{
recvBuff[n] = 0;
if(fputs(recvBuff, stdout) == EOF)
{
printf("\n Error : Fputs error\n");
}
}
if(n < 0)
{
printf("\n Read error \n");
}
return 0;
}
Output:$ ./newsc 127.0.0.1 Sun Dec 18 22:22:14 2011
Resource: http://www.thegeekstuff.com/2011/12/c-socket-programming/
Server Code 2:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main( int argc, char *argv[] )
{
int sockfd, newsockfd, portno, clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
/* First call to socket() function */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("ERROR opening socket");
exit(1);
}
/* Initialize socket structure */
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = 5001;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
/* Now bind the host address using bind() call.*/
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
{
perror("ERROR on binding");
exit(1);
}
/* Now start listening for the clients, here process will
* go in sleep mode and will wait for the incoming connection
*/
listen(sockfd,5);
clilen = sizeof(cli_addr);
/* Accept actual connection from the client */
newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr,
&clilen);
if (newsockfd < 0)
{
perror("ERROR on accept");
exit(1);
}
/* If connection is established then start communicating */
bzero(buffer,256);
n = read( newsockfd,buffer,255 );
if (n < 0)
{
perror("ERROR reading from socket");
exit(1);
}
printf("Here is the message: %s\n",buffer);
/* Write a response to the client */
n = write(newsockfd,"I got your message",18);
if (n < 0)
{
perror("ERROR writing to socket");
exit(1);
}
return 0;
}
Client code 2:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc, char *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[256];
if (argc < 3) {
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
/* Create a socket point */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("ERROR opening socket");
exit(1);
}
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
/* Now connect to the server */
if (connect(sockfd,&serv_addr,sizeof(serv_addr)) < 0)
{
perror("ERROR connecting");
exit(1);
}
/* Now ask for a message from the user, this message
* will be read by server
*/
printf("Please enter the message: ");
bzero(buffer,256);
fgets(buffer,255,stdin);
/* Send message to the server */
n = write(sockfd,buffer,strlen(buffer));
if (n < 0)
{
perror("ERROR writing to socket");
exit(1);
}
/* Now read server response */
bzero(buffer,256);
n = read(sockfd,buffer,255);
if (n < 0)
{
perror("ERROR reading from socket");
exit(1);
}
printf("%s\n",buffer);
return 0;
}
Resoruce: http://www.tutorialspoint.com/unix_sockets/socket_server_example.htm
SIMPLE CONCURRENT SERVER CODE:
* BLOCKING when do accepting for the connection
* forking child process for each new connection after accepting the connection
Server code 1:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main( int argc, char *argv[] )
{
int sockfd, newsockfd, portno, clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
/* First call to socket() function */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("ERROR opening socket");
exit(1);
}
/* Initialize socket structure */
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = 5001;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
/* Now bind the host address using bind() call.*/
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
{
perror("ERROR on binding");
exit(1);
}
/* Now start listening for the clients, here
* process will go in sleep mode and will wait
* for the incoming connection
*/
listen(sockfd,5);
clilen = sizeof(cli_addr);
while (1)
{
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
{
perror("ERROR on accept");
exit(1);
}
/* Create child process */
pid = fork();
if (pid < 0)
{
perror("ERROR on fork");
exit(1);
}
if (pid == 0)
{
/* This is the client process */
close(sockfd);
doprocessing(newsockfd);
exit(0);
}
else
{
close(newsockfd);
}
} /* end of while */
}
void doprocessing (int sock)
{
int n;
char buffer[256];
bzero(buffer,256);
n = read(sock,buffer,255);
if (n < 0)
{
perror("ERROR reading from socket");
exit(1);
}
printf("Here is the message: %s\n",buffer);
n = write(sock,"I got your message",18);
if (n < 0)
{
perror("ERROR writing to socket");
exit(1);
}
}
Client code:use above client code 2
Resoruce: http://www.tutorialspoint.com/unix_sockets/socket_server_example.htm
CUNCURRENT SERVER CODE without FORK but using Select:
practical example: https://www.scottklement.com/rpg/socktut/nonblocking.html
* The select system call is similar to the poll facility (examining the status of file descriptors of open input/output channels)
* there is no need for forked child process for handle each connection
* With select(), instead of having a process for each request, there is usually only one process that "multi-plexes" all requests, servicing each request as much as it can.
*
fd_set type arguments may be manipulated with four utility macros: FD_SET(), FD_CLR(), FD_ZERO(), and FD_ISSET().Advantage:
*main advantage of using select() is that your server will only require a single process to handle all requests.
*Thus, your server will not need shared memory or synchronization primitives for different 'tasks' to communicate.
Very basic code
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int main(void) {
fd_set rfds;
struct timeval tv;
int retval;
/* Watch stdin (fd 0) to see when it has input. */
FD_ZERO(&rfds);
FD_SET(0, &rfds);
/* Wait up to five seconds. */
tv.tv_sec = 5;
tv.tv_usec = 0;
retval = select(1, &rfds, NULL, NULL, &tv);
/* Don’t rely on the value of tv now! */
if (retval == -1)
perror("select()");
else if (retval)
printf("Data is available now.\n");
/* FD_ISSET(0, &rfds) will be true. */
else
printf("No data within five seconds.\n");
return 0;
}
Purpose of select:
http://stackoverflow.com/questions/14544621/why-is-select-used-in-linux
Resoruce:
http://www.tutorialspoint.com/unix_system_calls/_newselect.htm
http://www.lowtek.com/sockets/select.html
http://arunasujith.blogspot.in/2013/02/non-blocking-io-using-select-system.html
http://www.linuxquestions.org/questions/programming-9/select-system-call-usage-4175447393/
http://www.lowtek.com/sockets/select.html
http://www.cs.odu.edu/~cs779/spring11/lectures/select.html
https://www.quora.com/In-networking-programming-what-is-nonblocking-socket

No comments:
Post a Comment