Full integration of network programming concepts (IV). Implementation of C ++ and Java
Papaya 20080201
Some time ago, when I encountered something about network communication, I felt that it was necessary to sum up. Here are some new additions.
This example uses the C ++ method.
I. Socket. h header file
# Ifndef socket_h
# Define socket_h
# Include <stdio. h>
# Include <stdlib. h>
# Include <string. h>
# Include <fcntl. h>
# Include <sys/types. h>
# Include <sys/socket. h>
# Include <netinet/in. h>
# Include <netinet/tcp. h>
# Include <ARPA/inet. h>
# Include <unistd. h>
# Include <errno. h>
# Include <signal. h>
# Include <time. h>
Class socket
{
Public:
// Server listener (used by the server)
Int listen (INT iportid );
// The server obtains the connection bforkflag and determines whether the fork mode is used.
Int accept (bool bforkflag = false );
// Connect to the socket (used by the client)
Int connect (
// Remote Server IP Address
Char * sremotehostip,
// Remote server port
Int iremoteportid );
Socket ();
Virtual ~ Socket ();
// Socket common read
Int read (
// Store the buffer for reading socket content
Unsigned char * sbuffer,
// Specify the read Length
Int ilen );
// Socket normal write
Int write (
// Store the content address for writing to the socket
Unsigned char * sbuffer,
// Write the socket length
Int ilen );
// Socket Recv Method
Int Recv (
// Read content storage location
Unsigned char * sbuffer,
// Specify the read Length
Int ilen );
// Socket send Method
Int send (
// Send content
Unsigned char * sbuffer,
// Specify the sending Length
Int ilen );
Struct sockaddr_in m_servaddress;
Struct sockaddr_in m_clientaddress;
PRIVATE:
// Listener ID
Int m_ilistenid;
// Client segment connection received by the server
Int m_iacceptid;
// Client segment connection
Int m_isocketid;
};
# Endif
Ii. Contents of the socket. cpp file (omitted)
// Socket: the connection to the connect client segment is not implemented. You can enter it by yourself.
# Include "socket. H"
Using namespace STD;
Int socket: Listen (INT iportid)
{
}
Int socket: accept (bool bforkflag)
{
}
Int socket: connect (char * sremotehostip, int iremoteportid)
{
}
Socket: socket ()
{
This-> m_ilistenid =-1;
This-> m_iacceptid =-1;
This-> m_isocketid =-1;
}
Socket ::~ Socket ()
{
Close (this-> m_ilistenid );
Close (this-> m_iacceptid );
Close (this-> m_isocketid );
}
Int socket: Read (unsigned char * sbuffer, int ilen)
{
}
Int socket: Write (unsigned char * sbuffer, int ilen)
{
}
Int socket: Recv (unsigned char * sbuffer, int ilen)
{
}
Int socket: Send (unsigned char * sbuffer, int ilen)
{
}
Iii. server application sample code
{
Unsigned char srecvstring [command_max_len];
Unsigned char ssendstring [command_max_len];
Char scommand [command_max_len];
Char sip [20];
Int irecvlen;
Socket SRV;
SRV. Listen (16666 );
While (1 ){
Scommand [0] = 0;
Srecvstring [0] = 0;
SRV. Accept (0 );
Strcpy (SIP, inet_ntoa (SRV. m_clientaddress.sin_addr ));
Printf ("[get] Client Connection % s/n", SIP );
Irecvlen = srv. Recv (srecvstring, 200 );
Srecvstring [irecvlen] = 0;
Printf ("[get] client sending character: % s/n", srecvstring );
If (strlen (char *) srecvstring)> = 160 ){
Printf ("[Error] client sending error command: % s", srecvstring );
Strcpy (char *) ssendstring, "error ");
SRV. Send (ssendstring, 6 );
Continue;
}
If (strncmp (char *) srecvstring, "shutdownserv", 12) = 0 ){
Strcpy (char *) ssendstring, "exit ");
SRV. Send (ssendstring, 5 );
Return 0;
} Else
If (strncmp (char *) srecvstring, "startserv", 9 )! = 0 ){
Printf ("[Error] client sending error command: % s", srecvstring );
Strcpy (char *) ssendstring, "error ");
SRV. Send (ssendstring, 6 );
Continue;
}
Printf ("[EXE] Run the command: % s", scommand );
Strcpy (char *) ssendstring, "OK ");
SRV. Send (ssendstring, 3 );
System (scommand );
}
}
Iv. Client
Client connections can be written in any code. All you need to pay attention to must comply with the general specification. The specific implementation of different languages is as follows:
Difference.
For example, for a blocked Recv, sending does not require a loop body. Sometimes, when a loop body is used in C/C ++, no error occurs, but the Java client
There will be problems.
The following server code is not allowed:
Int num = 0;
Int ret;
If (this-> m_iacceptid <= 0 ){
Printf ("socket not connected/N ");
Return-1;
}
While (Num <ilen)
{
Ret =: Recv (this-> m_iacceptid, sbuffer, ilen, 0 );
If (Ret <0)
{Printf ("write error/N ");
Return-1;
}
Num + = ret;
}
Return num;
The following is the Java client code. You can enter the Java server code as required:
Import java.net .*;
Import java. Io .*;
Public class testclient {
Public static void main (string ARGs []) {
Try {
Socket socket = new socket ("192.168.0.99", 16666 );
Outputstream out = socket. getoutputstream ();
Inputstream in = socket. getinputstream ();
Byte [] btsend = new byte [80];
String test = new string ("abcdefg ");
Btsend = test. getbytes ();
Out. Write (btsend );
Out. Flush ();
Byte [] btrecv = new byte [10];
Int I = 0;
I = in. Read (btrecv );
Btrecv [I] = 0;
String strrecv = new string (btrecv, "US-ASCII ");
System. Out. println (I );
System. Out. println (strrecv );
Out. Close ();
In. Close ();
Socket. Close ();
} Catch (connectexception connexc ){
Connexc. printstacktrace ();
System. Err. println ("server connection failed! ");
} Catch (ioexception e ){
E. printstacktrace ();
}
}
}
5. Additional instructions
This article still lists the code, because most of the methods are described in detail in the previous series. Here, I would like to add
Setsockopt. Setsockopt (this-> m_ilistenid, sol_socket, so_reuseaddr, (char
*) & Optval, sizeof (optval ))! = 0 sets the reusable address. For more information, see the man manual.
The sample code is successfully debugged in hp unix gcc version 4.1.1 Linux eclipse 3.1.