Select Git revision
mysever.c 4.67 KiB
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <netdb.h>
#include <string.h>
#include <strings.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#define MAXFD 2
int main(int argc, char ** argv)
{
int sockfd, newsockfd, portno; // clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
socklen_t clilen;
int n;
char * c;//
if (argc < 3)
{
fprintf(stderr, "usage: %s ip port\n", argv[0]);
return 0;
}
/* Create TCP socket */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("ERROR opening socket");
exit(EXIT_FAILURE);
}
// reuse the socket if possible
int const reuse = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int)) < 0)
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
portno = atoi(argv[2]);
/* Create address we're going to listen on (given port number)
- converted to network byte order & any IP address for this machine */
bzero((char *)&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;//differ
serv_addr.sin_port = htons(portno); // store in machine-neutral format
/* Bind address to the socket */
if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
perror("ERROR on binding");
exit(EXIT_FAILURE);
}
/* Listen on socket - means we're ready to accept connections -
incoming connection requests will be queued */
listen(sockfd, 5);
clilen = sizeof(cli_addr);
/* Accept a connection - block until a connection is ready to
be accepted. Get back a new file descriptor to communicate on. */
/*newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
if (newsockfd < 0)
{
perror("ERROR on accept");
exit(EXIT_FAILURE);
}*/
// initialise an active file descriptors set
fd_set masterfds;
FD_ZERO(&masterfds);
FD_SET(sockfd, &masterfds);
// record the maximum socket number
int maxfd = sockfd;
while (1)
{
// monitor file descriptors
fd_set readfds = masterfds;
if (select(FD_SETSIZE, &readfds, NULL, NULL, NULL) < 0)
{
perror("select");
exit(EXIT_FAILURE);
}
// loop all possible descriptor
for (int i = 0; i <= maxfd; ++i)
// determine if the current file descriptor is active
if (FD_ISSET(i, &readfds))
{
// create new socket if there is new incoming connection request
if (i == sockfd)
{
int newsockfd = accept(sockfd, (struct sockaddr *)&cliaddr, &clilen);
if (newsockfd < 0)
perror("accept");
else
{
// add the socket to the set
FD_SET(newsockfd, &masterfds);
// update the maximum tracker
if (newsockfd > maxfd)
maxfd = newsockfd;
// print out the IP and the socket number
/*char ip[INET_ADDRSTRLEN];
printf(
"new connection from %s on socket %d\n",
// convert to human readable string
inet_ntop(cliaddr.sin_family, &cliaddr.sin_addr, ip, INET_ADDRSTRLEN),
newsockfd
);*/
}
}
// a message is sent from the client
else
{ /* Read characters from the connection, then process */
char buff[256];
int n = read(i, buff, 256);
if (n <= 0)
{
if (n < 0)
perror("read");
else
printf("socket %d close the connection\n", i);
close(i);
FD_CLR(i, &masterfds);
} // write back to the client
else if (write(i, buff, n) < 0)
{
perror("write");
close(i);
FD_CLR(i, &masterfds);
}
}
}
if (!strncmp(buffer, "GOODBYE-CLOSE-TCP", 17))
break;
/*c = buffer;
while (*c)
{
*c = toupper(*c);
++c;
}*/
/* close socket */
//close(sockfd);
return 0;
}