#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <error.h>
#include <sys/types.h> //process ID
#include <signal.h> //clear the Zombie process
//global variable for client server
char recv_msg[255]; //receive the massege from the client
char send_msg[255]; //send massege to the server
/*Inverse order function, reverse order of the received information*/
void reverse()
{
int recv_len = strlen(recv_msg),i; //the length of recv_msg; i for loop
for(i=0;i<recv_len;i++)
{
send_msg[i] = recv_msg[recv_len - i - 1]; //Inverse order for the massege
}
send_msg[i] = 0; //the last one is NULL to be the end of the alphabetic string
}
/*main function*/
int main(int argc, char *argv[])
{
struct sockaddr_in server_addr,peer_addr; //group addr
int server_sock_listen, server_sock_data;
int addr_len;
pid_t pid; //defining the process ID,requires the introduction of the header file #include <sys/types.h>
if(argc == 2) // example:./server2 port
{
//Specify the server address
server_addr.sin_family = AF_INET;
//INADDR_ANY Represents all native IP addresses
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(atoi(argv[1])); //set port number
memset(&server_addr.sin_zero, 0, sizeof(server_addr.sin_zero));
//fill zero to satisfy the length requirement because of the Inther
/*first step: create server:socket()*/
server_sock_listen = socket(AF_INET, SOCK_STREAM, 0);
if (server_sock_listen == -1)
{
perror("Create socket failed!");
return 0;
}
/*second step: binding socket and address:bind() including error handle*/
if(bind(server_sock_listen, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)
{
perror("Bind failed!"); //bind fail to say
if(close(server_sock_listen)==-1) //close the server listen socket for failing
{
perror("Close sock listen failed!"); //show listen sock close fail
}
return 0;
}
/*third step: monitor socket:listen() including error handle*/
if(listen(server_sock_listen, 0) == -1)
{
perror("Listen failed!"); //listen fail to say
if(close(server_sock_listen)==-1) //close the server listen socket for failing
{
perror("Close sock listen failed!"); //show listen sock close fail
}
return 0;
}
// continuous loop,error handling,create chlid process to handle each client separately
while(1)
{
printf("----Sever is listening...----\n");
/*fourth step: Accept() can accept more than one client*/
server_sock_data = accept(server_sock_listen, (struct sockaddr *)&peer_addr, &addr_len);
if(server_sock_data == -1)
{
perror("Accept failed"); //accept fail to say
if(close(server_sock_listen)==-1) //close the server listen socket for failing
{
perror("Close sock listen failed!"); //show listen sock close fail
}
return 0; //return 0 represents a normal exit of the program
}
else
{ //show the client the server has accepted
printf("Accept %s:%d\n",inet_ntoa(peer_addr.sin_addr),peer_addr.sin_port);
/*fifth step: fork() create multiple processes to implement concurrent services*/
signal(SIGCHLD,SIG_IGN); //clear the Zombie process
//the parent process returns the process number of the child process pid.The child process returns 0
pid = fork();
if(pid == -1) // fork failed
{
printf("fork error\n"); //show fail
return 1; //return 1 represents an abnormal exit of the program
}
else if(pid == 0) //fork succeed:child process to do
{
/**********************************the rest is as the same from the task1***********************************************/
/*sixth step: send()/recv()*/ while(1)
{
/* recv() and show */
//Accept group initialization is NULL
memset(recv_msg, 0, sizeof(recv_msg));
int recv_ret;//record the length of the massege from server
recv_ret = recv(server_sock_data, recv_msg, sizeof(recv_msg), 0);
//receive succeed
if(recv_ret > 0)
{
//show the massege the server recvive from which client
printf(" From %s:%d : %s\n",inet_ntoa(peer_addr.sin_addr), peer_addr.sin_port, recv_msg);
//while receiving "bye" or "Esc",close socket
if(strcmp(recv_msg, "bye") == 0 ||recv_msg[0] == 27)
{
printf("Close %s:%d\n",inet_ntoa(peer_addr.sin_addr),peer_addr.sin_port);
// Close server socket to exit
if(close(server_sock_data) == -1)
{
perror("Close sock data failed!");
return 0;
}
break;
}
}
else if(recv_ret == 0) //The other party has closed the connection
{
// Close server socket to exit
if(close(server_sock_data) == -1)
{
perror("Close sock data failed!");
return 0;
}
}
else
{
perror("Recv failed!");
return 0;
}
/*input and send()*/
reverse(); //Call function for inverse order Transformation of Information
//show what the server replys to the client who sent the massege just
printf(" Reply %s:%d : %s\n",inet_ntoa(peer_addr.sin_addr), peer_addr.sin_port, send_msg);
if(send(server_sock_data, send_msg, strlen(send_msg), 0) == -1)
{
perror("Reply failed!");return 0;
}
}
}
else //close the parent process
{
// Close server socket to exit
//if(close(server_sock_data) == -1)
//{
// perror("Close sock data failed!");
//}
}
}
}//first while(1) end
/*seventh step: close listen socket */
if(close(server_sock_listen) == -1)
{
perror("Close sock listen failed!");return 0;
}
}//the argc number is 2, as server :./server2 port
else
{
printf("argc error!\n"); //the argc number is not right,cannot run
return 0;
}
}//main end
评论12