Tcp client and server communication

Source: Internet
Author: User
Tags socket error htons

 

/*************************************** **************************************** ***

The following is the communication between the tcp client and the server. The same TCP connection sends "Hello!" every five seconds !", Until the network fails or the program is forced to exit. If the client exits abnormally, the daemon can be automatically restarted.

This program refers to "UNIX network programming", and the header file directly uses the packaged header (with some modifications) in the book)

Env:

My server is running here:

HP-UX hp94 B .11.11 U 9000/800 4183772791 unlimited-User License

The client runs here:

Linux iprn215 2.4.21-32.el #1 Fri Apr 15 21:29:19 EDT 2005 i686 i686 i386 GNU/Linux

Server configuration file:

Listen_port 60005

Client configuration file:

Tcptest_seraddr 192.168.2.89
Tcptest_serport 60005

Note: In order to test the transient disconnection of the network, I originally wanted to find a ready-made TCP communication program. However, the sample program on the network uses a socket for sending and receiving operations, and then closes the program. Therefore, you can only write it on your own. Refer to "UNIX network programming". When I write my daemon, I follow the classic routine in the book. As a result, a "crazy process" is generated, and no matter what method I want, it cannot be killed, I am still living crazy now (I will kill it sooner or later! Haha...) However, after a few days of research, we finally achieved the basic functions, but we still have nothing to do with the stability of our own programs! If any expert gives you some advice, I am very grateful and grateful ......

The last thing I want to talk about is that my program is very poor, but I hope to give you some advice. In addition, if someone has the same troubles as I used, I cannot find a suitable example. I hope my bricks can help me!

Pai_^

**************************************** **************************************** **/

Server:

/* Contains an init, which starts the server and enables the server to run in the background without occupying this Windows Terminal */

Server/init:

# Include "unp. H"

# Include "error. c"

# Include "wrap. c"

Void myinit ()

{

Char filename [50];

Char * cindir = getenv ("cindir ");

If (cindir = NULL)

Exit (0 );

If (Fork () = 0)

{

Memset (filename, 0, sizeof (filename ));

Sprintf (filename, "% S/bin/tcptest_server", cindir );

Chdir ("/");

Umask (0 );

Execlp (filename, "tcptest_server", (char *) 0 );

_ Exit (0 );

}

}

Int main (void)

{

Void sig_chld (INT );

If (Fork ()! = 0) _ exit (0 );

// In the INIT process:

Setsid ();

Myinit ();

Exit (0); // The purpose of this daemon is to remove the server from the terminal.

}

Server/tcpserver. C:

# Include "wrap. c"

# Define maxlistennum 10
Int linenum = 0;

Void writelog (const char * FMT ,...);
Void changelogfile ();

Void alarmfunc (INT signo)
{
Writelog ("receive client msg timeout! /N ");
Exit (0); // if the receiving message times out, the sub-process processing the client exits.
}

Void sig_chld (INT signo)
{
Pid_t PID;
Int Stat;
While (pid = waitpid (-1, & stat, wnohang)> 0)
{
// Printf ("child % d terminated! /N ", pid );
Writelog ("socket terminated: % d", pid );
}
Signal (sigchld, sig_chld );
}

Void writelog (const char * FMT ,...)
{
Time_t timer;
Struct TM * PTM;
Char wday [20];
Int N;
Char Buf [256];
Char logfilename [50];
File * FP;
Char * cindir = getenv ("cindir ");
Sprintf (logfilename, "% S/log/tcptest_server.log", cindir );
If (FP = fopen (logfilename, "A +") = NULL)
{
Printf ("open log file error! /N ");
Exit (0 );
}

Timer = Time (null );
PTM = localtime (& timer );
Memset (wday, 0, sizeof (wday ));
Switch (PTM-> tm_wday)
{
Case 0: strcpy (wday, "Sunday"); break;
Case 1: strcpy (wday, "Monday"); break;
Case 2: strcpy (wday, "Tuesday"); break;
Case 3: strcpy (wday, "Wednesday"); break;
Case 4: strcpy (wday, "Thursday"); break;
Case 5: strcpy (wday, "Friday"); break;
Case 6: strcpy (wday, "Saturday"); break;
}
 
Memset (BUF, 0, sizeof (BUF ));
Sprintf (BUF, "% 04d/% 02d/% 02d % S % 02d: % 02d: % 02d | ",
(1900 + PTM-> tm_year ),
PTM-> tm_mon,
PTM-> tm_mday,
Wday,
PTM-> tm_hour,
PTM-> tm_min,
PTM-> tm_sec );

N = strlen (BUF );
Va_list AP;
Va_start (AP, FMT );
# Ifdef have_vsnprintf
Vsnprintf (BUF + N, 256, FMT, AP );
# Else
Vsprintf (BUF + N, FMT, AP );
# Endif
Va_end (AP );

Fprintf (FP, Buf, strlen (BUF ));
Fprintf (FP, "/R/N ");
Fclose (FP );
Linenum ++;
// Printf ("linenum: % d/N", linenum );
Changelogfile ();
Return;
}

Void changelogfile ()
{
Char logfilename [50];
File * FP;
Char * cindir = getenv ("cindir ");
Sprintf (logfilename, "% S/log/tcptest_server.log", cindir );

If (linenum> 30000)
{
Linenum = 0;
Char oldfilename [256];
Char newfilename [256];

Time_t timer;
Struct TM * PTM;

Timer = Time (null );
PTM = localtime (& timer );
Sprintf (oldfilename, "% S. % 04d % 02d % 02d % 02d % 02d ", logfilename, (INT) PTM-> tm_year + 1900, (INT) PTM-> tm_mon + 1, (INT) PTM-> tm_mday,
(INT) PTM-> tm_hour, (INT) PTM-> tm_min );
Unlink (oldfilename );
Rename (logfilename, oldfilename );

If (FP = fopen (logfilename, "WT") = NULL)
Printf ("can not open log file: % s/n", logfilename );
Else
Fclose (FP );
}
}

Int main (INT argc, char * argv [])
{
Int sockfd, clientfd;
Time_t timer;
Struct TM * PTM;
Char STR [100];
Pid_t PID;
Pid_t childpid;
Struct sockaddr_in serveraddr;
Struct sockaddr_in clientaddr;
# Ifdef _ Aix
Socklen_t sin_size;/* 234 mod for ibmtest */
# Elif _ Linux
Socklen_t sin_size;
# Else
Int sin_size;
# Endif
// Int sin_size;
Int N;
Char Buf [8];
Void sig_chld (INT );
Printf ("| --------------------------------------------/N ");
Printf ("| ---- tcptest server begin init.../N ");

File * cfgreen;
Char * cindir = getenv ("cindir ");
Char character filename [100];
Sprintf (using filename, "% S/etc/tcptest_server.config", cindir );
Cfgreen = fopen (Response filename, "RT ");
If (cfgreen = NULL)
{
Printf ("can not open config file! /N ");
Exit (1 );
}

Int listenport = 0;
Char temp [256];
Fscanf (cfgreen, "% s", temp );
If (strcmp (temp, "listen_port") = 0)
{
Fscanf (cfgreen, "% s", temp );
Listenport = atoi (temp );
}
Else
Printf ("read config error! /N ");
Fclose (cfgreen );

Printf ("| ---- read config OK! /N ");

Signal (sigchld, sig_chld );

// Create a socket
If (sockfd = socket (af_inet, sock_stream, 0) <0)
{
// Fprintf (logfp, "creat socket error! ");
Writelog ("creat socket error: % s! ", Strerror (errno ));
Exit (1 );
}
Printf ("| ---- create socket OK! /N ");

// Fill Structure
Bzero (& serveraddr, sizeof (struct sockaddr_in ));
Serveraddr. sin_family = af_inet;
Serveraddr. sin_addr.s_addr = htonl (inaddr_any );
Serveraddr. sin_port = htons (listenport );

// Bind
If (BIND (sockfd, (struct sockaddr *) & serveraddr, sizeof (struct sockaddr) <0)
{
// Fprintf (logfp, "BIND error! /N ");
Writelog ("BIND error: % s! ", Strerror (errno ));
Exit (1 );
}

Printf ("| ---- bind socket OK! /N ");

// Listen
If (Listen (sockfd, maxlistennum ))
{
// Fprintf (logfp, "Listen error! /N ");
Writelog ("Listen error: % s! ", Strerror (errno ));
Exit (1 );
}

Printf ("| ---- listen socket OK! /N ");
Printf ("| --------------------------------------------/N ");
For (;;)
{
Sin_size = sizeof (struct sockaddr_in );
If (clientfd = accept (sockfd, (struct sockaddr *) & clientaddr, & sin_size) <0)
{
If (errno = eintr)
Continue;
Else
{
// Fprintf (logfp, "Accept error! /N ");
Writelog ("Accept error: % s! ", Strerror (errno ));
Exit (1 );
}
}
Writelog ("Accept OK: Client: % d! ", Clientfd );

If (childpid = fork () = 0)
{
Writelog ("the child server fork OK: % d! /N ", getpid ());
Close (sockfd );
Signal (sigalrm, alarmfunc );
Alarm (10); // if the client exits unexpectedly, the read timeout value is 8 seconds.
While (n = read (clientfd, Buf, maxline ))! =-1) // The end-to-end is terminated normally (close is displayed). Only-1 is read here. If the end-to-end is Ctrl + C, the end-to-end sequence is not followed.
{
If (n> 0 ){
Alarm (10 );
Write (clientfd, Buf, N );
Writelog ("receive and send MSG: % s", Buf );
If (strcmp (BUF, "Hello! ")! = 0)
Writelog ("receive string error: % s", Buf );
}
Else // if no data is input to the peer end, the value is 0.
Continue;
}
Exit (0 );
}
Close (clientfd );
}
Exit (0 );
}

 

Client:

Client/init:

Int initnum = 0;

Void myinit (INT initflag)
{
Char filename [50];
Char * cindir = getenv ("rndir ");
If (cindir = NULL)
Exit (0 );
If (initflag = 1)
Sleep (5 );
If (initflag = 2)
Sleep (10 );
If (initflag = 3)
Sleep (20 );
If (initflag = 4)
Sleep (40 );

If (Fork () = 0)
{
Memset (filename, 0, sizeof (filename ));
Sprintf (filename, "% S/bin/tcptest_client", cindir );
Chdir ("/");
Umask (0 );
Execlp (filename, "tcptest_client", (char *) 0 );

_ Exit (0 );
}
}

Void sig_chld (INT signo) // The sub-process can be entered here only after the sub-process ends.
{
Pid_t PID;
Int Stat;
Signal (sigchld, sig_chld );
 
While (pid = waitpid (-1, & stat, wnohang)> 0)
{
Initnum ++; // if the client connection fails, the sub-process will exit and try to restart for 12 times.
If (initnum> 4)
{
// Exit (0); // keep it connected until it is connected, or force exit
Initnum = 0;
}
Myinit (initnum );
}
}

Int main (void)
{
Void sig_chld (INT );

// Printf ("the main PID: % d/N", getpid ());
 
If (Fork ()! = 0) _ exit (0 );
// In the INIT process:
Signal (sigchld, sig_chld );
Setsid ();
 
Myinit (0 );

For (;;)
{
Sleep (10 );
}
}

Client/tcpclient. C:

# Include "wrap. c"

Void changelogfile ();
Void writelog (const char * FMT ,...);
Int linenum = 0;

Void sig_chld (INT signo) // The sub-process can be entered here only after the sub-process ends.
{
Int I;
Pid_t PID;
Pid_t ppid;
Int Stat;

While (pid = waitpid (-1, & stat, wnohang)> 0)
{
Printf ("the child terminal: % d/N", pid); // no input
}

Exit (0 );
}

Void writelog (const char * FMT ,...)
{
Time_t timer;
Struct TM * PTM;
Char wday [20];
Int N;
Char Buf [256];
Char logfilename [50];
File * FP;
Char * cindir = getenv ("rndir ");
Sprintf (logfilename, "% S/log/tcptest_client.log", cindir );
If (FP = fopen (logfilename, "A +") = NULL)
{
Printf ("open log file error! /N ");
Exit (0 );
}

Timer = Time (null );
PTM = localtime (& timer );
Memset (wday, 0, sizeof (wday ));
Switch (PTM-> tm_wday)
{
Case 0: strcpy (wday, "Sunday"); break;
Case 1: strcpy (wday, "Monday"); break;
Case 2: strcpy (wday, "Tuesday"); break;
Case 3: strcpy (wday, "Wednesday"); break;
Case 4: strcpy (wday, "Thursday"); break;
Case 5: strcpy (wday, "Friday"); break;
Case 6: strcpy (wday, "Saturday"); break;
}
 
Memset (BUF, 0, sizeof (BUF ));
Sprintf (BUF, "% 04d/% 02d/% 02d % S % 02d: % 02d: % 02d | ",
(1900 + PTM-> tm_year ),
PTM-> tm_mon,
PTM-> tm_mday,
Wday,
PTM-> tm_hour,
PTM-> tm_min,
PTM-> tm_sec );

N = strlen (BUF );
Va_list AP;
Va_start (AP, FMT );
# Ifdef have_vsnprintf
Vsnprintf (BUF + N, 256, FMT, AP );
# Else
Vsprintf (BUF + N, FMT, AP );
# Endif
Va_end (AP );

Fprintf (FP, Buf, strlen (BUF ));
Fprintf (FP, "/R/N ");
Fclose (FP );
Linenum ++;
// Printf ("linenum: % d/N", linenum );
Changelogfile ();
Return;
}

Void changelogfile ()
{
Char logfilename [50];
File * FP;
Char * cindir = getenv ("rndir ");
Sprintf (logfilename, "% S/log/tcptest_client.log", cindir );

If (linenum> 30000)
{
Linenum = 0;
Char oldfilename [256];
Char newfilename [256];

Time_t timer;
Struct TM * PTM;

Timer = Time (null );
PTM = localtime (& timer );
Sprintf (oldfilename, "% S. % 04d % 02d % 02d % 02d % 02d ", logfilename, (INT) PTM-> tm_year + 1900, (INT) PTM-> tm_mon + 1, (INT) PTM-> tm_mday,
(INT) PTM-> tm_hour, (INT) PTM-> tm_min );
Unlink (oldfilename );
Rename (logfilename, oldfilename );

If (FP = fopen (logfilename, "WT") = NULL)
Printf ("can not open log file: % s/n", logfilename );
Else
Fclose (FP );
}
}

Int
Main (INT argc, char ** argv)
{
Int I, sockfd;
Int port;
Char Address [21] = "127.0.0.1 ";
Struct sockaddr_in servaddr;
 
Char sendbuf [8];
Sprintf (sendbuf, "Hello! ");
Char recvbuf [10];

Char character filename [50];
File * cfgreen;
Char * cindir = getenv ("rndir ");
Sprintf (using filename, "% S/config/tcptest_client.config", cindir );

If (cfgreen = fopen (canonical filename, "A +") = NULL)
{
Printf ("Open config file error! /N ");
Exit (0 );
}

Char temp [256];
While (fscanf (cfgreen, "% s", temp )! = EOF)
{
If (strcmp (temp, "tcptest_seraddr") = 0)
{
Memset (address, 0, sizeof (Address ));
Fscanf (cfgreen, "% s", address );
}
Else if (strcmp (temp, "tcptest_serport") = 0)
Fscanf (cfgreen, "% d", & Port );
Else
Printf ("read config error! /N ");
}
Fclose (cfgreen );

Sockfd = socket (af_inet, sock_stream, 0 );
 
Bzero (& servaddr, sizeof (servaddr ));
Servaddr. sin_family = af_inet;
Servaddr. sin_port = htons (port );
Inet_ton (af_inet, address, & servaddr. sin_addr.s_addr );
 
Writelog ("Connect server begin ......");
 
If (connect (sockfd, (struct sockaddr *) & servaddr, sizeof (servaddr) <0)
{
Writelog ("Connect server error: % s! ", Strerror (errno ));
Exit (0 );
}
 
Writelog ("Connect server OK! /N ");
 
For (;;)
{
Write (sockfd, sendbuf, 8 );
Read (sockfd, recvbuf, 10 );
// Fprintf (stdout, "% s", recvbuf );
Writelog ("receive MSG: % s", recvbuf );
If (strcmp (recvbuf, "Hello! ")! = 0)
Writelog ("receive string error: % s", recvbuf );
Sleep (5 );
}
Close (sockfd );

_ Exit (0 );
}

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.