Implementation of point-to-point chat room-c language under RedHat

Implementing point-to-point chat room under RedHat

Point to point chat room provides a platform for people to communicate, and it has a high degree of privacy and convenience. By providing a perfect network chat system, we can achieve the purpose of communication and contact between people.

development environment

VMware Workstation 15 Pro

Red Hat Enterprise Linux 5

Each person has a computer and can connect to the local area network

Basic functions of the system

(1) Server:

① receive the data sent by the client and display

② accept the data input by the keyboard and send it to the client

③ when the client is closed, all the processes on the server will exit.

(2) Client:

① receive the data sent by the server and display

② accept the data input by the keyboard and send it to the server

③ when the server is shut down, all processes of the client will exit.

Server side programming (p2pserv.c)


#include <stdio.h>//It is the content to be processed before the program is compiled, which is called compile preprocessing command.

#include <stdlib.h>//Statement means to include stdlib.h in the program.

#include <string.h>//It is the content to be processed before the program is compiled, which is related to the call of string.

#include <unistd.h>//The name of the header file that provides access to the POSIX Operating System API.

#include <arpa/inet.h>//It mainly defines the format conversion function.

#include <sys/socket.h> //Provide socket function and data structure.

#include <signal.h>//It defines how to handle different signals when the program executes.

/*Error redefinition*/

#define ERR_EXIT(m)\

do\

{\

        perror(m);\//Output the cause of the error in the previous function to the standard device.

        exit(EXIT_FAILURE);\//
//Represents an abnormal exit.

}while(0)

/*Signal processing function*/ 

void handler(int sig)

{

    printf("recv
a sig=%d\n", sig);

    exit(EXIT_SUCCESS);//
//Indicates that the program terminated successfully

}

/*Start main program*/

int main(int argc,char *argv[]) 

{

int listenfd; //Define listening socket and client socket

int connfd; 

struct sockaddr_in servaddr; 

struct sockaddr_in clntaddr; 

socklen_t clntaddr_size; 

pid_t pid; //Define thread tag variables

if(argc!=2) 

{ 

  
printf("usage:%s,<port>\n",argv[0]); 

  
exit(1); 

}

/*Create server socket*/

listenfd=socket(PF_INET,SOCK_STREAM,0); //Generate a TCP socket

if(listenfd==-1) 

   ERR_EXIT("socket");


/*Initialize local address information*/

memset(&servaddr,0,sizeof(servaddr)); //The function is to fill a given value in a block of memory

servaddr.sin_family=AF_INET; //When creating a socket, use this field to specify the address family

servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
//Listen to all addresses of the client

servaddr.sin_port=htons(atoi(argv[1])); 

/*Assign address information to socket*/

if(bind(listenfd,(struct sockaddr
*)&servaddr,sizeof(servaddr))==-1)

    ERR_EXIT("bind");


/*Call the listen function to enter the wait for connection request state. At this time, the socket becomes a passive socket, which is responsible for listening*/

if(listen(listenfd,5)==-1) 

   
ERR_EXIT("listen");

/*Call the accept function to take a connection request from the queue header to establish a connection with the client, and return the created socket descriptor, conn_sock is mainly used to communicate with customers, while the previous serv_sock is mainly used for monitoring*/

connfd=accept(listenfd,(struct sockaddr
*)&clntaddr,&clntaddr_size); 

if(connfd==-1) 

   
ERR_EXIT("accept"); 

else 

     printf("recv connect
ip=%s,port=%d\n",inet_ntoa(clntaddr.sin_addr),ntohs(clntaddr.sin_port)); //output

pid_t pid;

pid=fork( );//Create child process 

if(pid==-1)

   
ERR_EXIT("fork");

if(pid>0) //The parent process is responsible for receiving the data sent by the client 

{

   
char recvbuf[1024];

while(1)

   
{ 

      
memset(recvbuf,0,sizeof(recvbuf));

      
int str_len=read(connfd,recvbuf,sizeof(recvbuf));

      
if(str_len==-1)

          
ERR_EXIT("read");

      
if(str_len==0)

      
{

      
    printf("Client closed\n");

          
break;

      
}

printf("Message from client:");

      
fputs(recvbuf,stdout);

    
}

      
close(connfd);

      
close(listenfd);

      
printf("parent close\n");

          kill(pid, SIGUSR1); //Call kill function to send signal to subprocess 

        exit(EXIT_SUCCESS);

}

else if(pid==0)

{

  
signal(SIGUSR1, handler);//Once the SIGUSR1 signal is received, the handler function is called for processing 

    char
sendbuf[1024];

        
       while(fgets(sendbuf,sizeof(sendbuf),stdin)!=NULL)

  {

       
write(connfd,sendbuf,sizeof(sendbuf));

       
memset(sendbuf,0,sizeof(sendbuf));

  } 

}

 
return 0;

}

Client programming (p2pclint.c)


#include <stdio.h>//It is the content to be processed before the program is compiled, which is called compile preprocessing command.

#include <stdlib.h>//Statement means to include stdlib.h in the program.

#include <string.h>//It is the content to be processed before the program is compiled, which is related to the call of string.

#include <unistd.h>//The name of the header file that provides access to the POSIX Operating System API.

#include <arpa/inet.h>//It mainly defines the format conversion function.

#include <sys/socket.h> //Provide socket function and data structure.

#include<signal.h>//It defines how to handle different signals when the program executes.

/*Error macro definition*/

#define ERR_EXIT(m)\ //Define error exit

do\ 

{\ 

  
perror(m);\ 

  
exit(EXIT_FAILURE);\ //On behalf of abnormal exit

}while(0) 

/*Signal processing function*/ 

void handler(int sig)

{

    printf("recv
a sig=%d\n", sig);

    exit(EXIT_SUCCESS);//Indicates that the program terminated successfully

}

/*Start main program*/

int main(int argc,char *argv[]) 

{ 

   int
sock; 

  
struct sockaddr_in servaddr;// Declared a struct
sockaddr_in Variable of type

    char
sendbuf[1024];// A sendbuf array of size 1024 is defined

    if(argc!=3) //Get information error prompt. But don't stop running any code

   {


printf("usage:%s,<IP>
<port>\n",argv[0]); 

     
exit(1); 

} 

/*Create a socket to connect to the server*/ 

 
sock=socket(PF_INET,SOCK_STREAM,0); // socket() system call with three parameters

 
if(sock==-1) 

     
ERR_EXIT("socket"); 

memset(&servaddr,0,sizeof(servaddr)); 

  servaddr.sin_family=AF_INET;
//When creating a socket, use this field to specify the address family. For TCP/IP protocol, it must be set to AF_INTE. 

servaddr.sin_addr.s_addr=inet_addr(argv[1]);


  servaddr.sin_port=htons(atoi(argv[2])); 

  /*Establish a connection with the server*/ 

if(connect(sock,(struct sockaddr *)&servaddr,sizeof(servaddr))==-1)


     
ERR_EXIT("connect"); 

 
else 

     
printf("Connected......\n"); 

 
pid_t pid;// A pid is defined_ Variable pid of type T

 
pid=fork();//The fork() function returns a process number assigned to pid

  /*The parent process is responsible for receiving data from the keyboard and transmitting it to the server*/

 
if(pid>0)

  {

    
signal(SIGUSR1, handler);//Once the SIGUSR1 signal is received, the handler function is called for processing 

      while(fgets(sendbuf,sizeof(sendbuf),stdin)!=NULL)

    
{

    
    write(sock,sendbuf,sizeof(sendbuf));

         memset(sendbuf,0,sizeof(sendbuf));

       
}

   
}

/*Subprocess, responsible for receiving data from the server and displaying*/ 

else if(pid==0)

 { 

     char recvbuf[1024];// A recvbuf array of size 1024 is defined

     
while(1)

     
{

          
int str_len=read(sock,recvbuf,sizeof(recvbuf));

       
   if(str_len==0)

         
{ 

     
           printf("server closed\n");

                 break;

          
} 

else if(str_len<0)

                ERR_EXIT("read");

           printf("Message from
server:");

           fputs(recvbuf,stdout);

           memset(recvbuf,0,sizeof(recvbuf));

        } 

      close(sock);

       kill(getppid( ), SIGUSR1);////Call the kill function to send the signal to

   }

 
else

     
ERR_EXIT("fork");

 
return 0;

}

Operation results

  1. Put the edited client "p2pclint.c" file and server "p2pserv.c" file in the created "PTP"_ chat_ Under the "room" folder, as shown in the following figure.

  2. Click the right mouse button under this file to pop up the menu, and select "open in terminal" to open the terminal.

  3. In the terminal window, enter the gcc command to compile the client and server files.

  4. Reopen a terminal window and enter ". / p2pserv 5678" to open the server (5678 is the port number).

  5. Reopen a terminal window and input ". / p2pclint 127.0.0.1 5678" to open the client

  6. Messages sent in both windows can be received and run successfully.

Tags: socket network Programming Vmware

Posted on Fri, 19 Jun 2020 22:13:07 -0400 by daftdog