Socket programming-technical implementation

Source: Internet
Author: User

Socket implementation

I have been playing with socket for the past few days. I have some experiences and I will post them to share with you. If anything is inappropriate or wrong, please kindly advise me.

What is socket? Socket is.... I won't copy books here. If you are interested, check the books.
However, socket is a communication method between different processes. Just like making a phone call is a communication method between friends. Personal Understanding: the so-called "communication" means sending data between each other. Someone understands that socket is a communication between different computers.
Is inaccurate. Both processes run on the same computer or on different computers.
Socket technology for communication.

The use of socket sockets requires support from NICs. Therefore, sockets are generally used for communication between different machines. If two processes communicate on the same computer, generally, the more efficient shared memory technology is used.

Communication between two processes requires both processes to run at the same time (nonsense). In specific implementation, we usually need to treat the two processes differently, A process waits for another process to send a message to itself. After receiving the message, it processes the message and sends the result back. We call processes that process messages and provide services as servers and processes that process messages and requests as clients. The general process is that the client sends a message to the server. The server process receives the message for processing and sends the processing result to the client. Well, that's it.

Another problem is that if I have a process that needs to communicate with a process on another computer through socket, how can I specify another process in this process? Another concept is port. If the operating system is compared to a house, the port is the window of the house and the channel for communication between the system and the system. In socket implementation, we do not specify another process, but specify the port number for sending or receiving messages. For example, if process a sends a message to process B, the message is sent to the port N of the computer running process B, and process B is monitoring port N at this time, in this way, process B can receive the data sent by process A, and process B also sends the message to this port. process a can also receive the data sent by process B from this port. Of course, this requires the client and the server to agree on the port number, that is, to operate on the same port together. If the client sends messages to port N1 while the server monitors port N2, the communication will fail. The maximum port number is 65535, which cannot be greater than this. However, we should try not to use a port number smaller than 1024 in our own programs. Many ports smaller than 1024 are used by the system, for example, 23 is used by Telnet.

The socket implementation is very simple. As long as you follow certain steps, you can immediately establish such a communication channel.

The following describes several core functions in detail:

Socket socket (int af, int type, int Protocol );
The following function must be used first on both the client and server.
This function is intended to tell the system to prepare a socket channel for me to communicate with other processes. The Return Value of the function is very important. We need to write it down. It indicates the socket channel that the system has prepared for us. It will be used in every socket-related function in the future. If this value is equal to socket_error, indicates that the function execution failed. The function parameters are pf_inet, sock_stream, and ipproto_tcp.

Int BIND (socket S, const sockaddr * ADDR, int namelen );
This function is only used by server programs and is used to bind a socket channel. The return value can be used to determine the execution result of the function. If it is equal to socket_error, it will fail. The first parameter S is the return value of the socket () function. In the structure ADDR, We need to specify a port number; namelen is equal to the size of the sockaddr structure.

Int listen (socket S, int backlog );
This function is only used by the server program and is used to listen to this port. The returned value is the same as that of the BIND function.

Int accept (socket S, sockaddr * ADDR, int * addrlen );
This function is only used by the server program and is used to respond to client connections. The returned value is the same as that of the BIND function.

Int connect (socket S, const sockaddr * Name, int namelen );
This function is only used by the client program and serves to establish a connection between the client and a port of a computer. The returned value is the same as that of the BIND function. The first parameter S is the return value of the socket () function. In the structure name, we need to specify a port number and the target machine name; namelen is equal to the size of the sockaddr structure.

Int send (socket S, char * Buf, int Len, int flags );
Int Recv (socket S, char * Buf, int Len, int flags );
These two functions are used to send and receive data. both the client and the server can use them. Which one can send and which one can receive the data? Haha.
From the return value of the function, you can check whether the function execution is successful. In the parameter, Buf is the pointer to the data sent or received, and Len is the data length. Flags can be set to 0 (in fact, I don't know the specific meaning ).

The last step is to close the socket, which is easy to forget, but this function is very important and must be used.
Int closesocket (socket S );

Well, there are several key functions, which are the execution sequence of these functions:

Client Service

|
V v
Socket () socket ()
|
| V
| BIND ()
|
| V
| Listen ()
|
| V
| Accept () is suspended until a client is connected.
|
Three-segment handshake process |
Connect () <-------------> |
|
V send message v
+ ---> Send () -------------> Recv () <------- +
|. |
|. Process a message |
| V Response Message. |
+ ---- Recv () <--------------- send () -------- +
|
V |
Close () ---------------> Recv ()
|
V
Closesocket ()

I think it is a good description of the running track of the client and server.

You can use the preceding functions to establish a socket communication connection on Linux. However, if you use another function on Windows:
Int wsastartup (word wversionrequested, lpwsadata );
In Windows, you must first execute this function. Therefore, you must put this function before the socket () function.

I have encapsulated the above functions. To save space, I have removed all comments and non-important functions. Here I can see the specific usage of each function:

In the vc60 environment, run the following functions, including the header files errno. h and winsock2.h, and connect to the ws2_32.dll file during connection.

This is the header file content:
Class socket {
Public:

Bool setup ();

Void close ();

Bool connect (string host, int port );

Bool listen ();

Int accept ();

Int Recv (char * Buf, int Len );

Int Recv (INT new_fd, char * Buf, int Len );

Int send (const char * MSG, int Len );

Int send (INT new_fd, const char * MSG, int Len );

PRIVATE:
Int _ FD;
};

This is the content of the implementation file:
Bool socket: setup (){

Wsadata WSD;
_ FD = wsastartup (makeword (2, 2), & WSD );
If (_ FD ){
Return false;
}

_ FD =: socket (pf_inet, sock_stream, ipproto_tcp );
If (_ FD =-1 ){
Return false;
}
Return true;
}

Bool socket: Listen (){
Struct sockaddr_in my_addr;
 
My_addr.sin_family = af_inet;
My_addr.sin_port = htons (52309 );
My_addr.sin_addr.s_addr = inaddr_any;
 
If (: BIND (_ FD, (struct sockaddr *) & my_addr, sizeof (struct sockaddr) = socket_error ){
Return false;
}

If (: Listen (_ FD, backlog) = socket_error ){
Return false;
}

Return true;
}

Int socket: accept ()
{
Int new_fd;
Struct sockaddr_in their_addr;
Int sin_size = sizeof (their_addr );
 
Printf ("accepting.../N ");

New_fd =: accept (_ FD,
(Struct sockaddr *) & their_addr,
& Sin_size );
Return new_fd = socket_error? -1: new_fd;
}

Bool socket: connect (string host, int port ){
Struct hostent * _ H = gethostbyname (host. c_str ());
If (_ H = 0 ){
Return false;
}

Struct in_addr * _ ADDR = (struct in_addr *) _ H-> h_addr;
Struct sockaddr_in sin;
Sin. sin_family = af_inet;
Sin. sin_addr = * _ ADDR;
Sin. sin_port = htons (port );

If (: connect (_ FD, (sockaddr *) & sin, sizeof (SIN) = socket_error ){
Return false;
}

Return true;
}

Int socket: Recv (INT new_fd, char * Buf, int Len)
{
Int NB =: Recv (new_fd, Buf, Len, 0 );
If (NB =-1 ){
Printf ("error! Recv./N ");
}
Return NB;
}

Int socket: Recv (char * Buf, int Len ){
Return Recv (_ FD, Buf, Len );
}

Int socket: Send (const char * MSG, int Len ){
Return send (_ FD, MSG, Len );
}

Int socket: Send (INT new_fd, const char * MSG, int Len)
{
Int NB =: Send (new_fd, MSG, Len, 0 );
If (NB =-1 ){
Printf ("error! Send./N ");
}

Return NB;
}

Void socket: Close (){

Int trytimes = 0;
While (: closesocket (_ FD) & trytimes <close_try_times)
Trytimes ++;

If (trytimes = 10 ){
Printf ("cannot close socket! /N ");
}
}

Well, the socket class is encapsulated, and the following is the organization. The server side and the client side are different. The code below is given separately. It is very simple here.

Client:
Int main (INT argc, char ** argv)
{
Printf ("Socket of client is run.../N ");
Socket S;
If (! S. Connect ("dezhi", 52309 ))
Return 0;

Char * MSG = "OK, send a message .";
For (INT I = 0; I <10; I ++ ){
S. Send (MSG, 20 );
Printf ("message = % s/n", MSG );
}
S. Send ("Q", 1 );
S. Close ();

Return 0;
}

Server:
Int main (INT argc, char ** argv ){
Printf ("Socket of service is run.../N ");

Socket S;
S. Listen ();
Int new_fd = S. Accept ();

Char Buf [8];
Buf [7] = '/0 ';
While (1 ){
If (S. Recv (new_fd, Buf, 5 )! =-1 ){
Printf ("% s/n", Buf );
If (BUF [0] = 'q ')
Break;
}
}
S. Close ();
}

The running result is as follows:
Client:
Socket of client is run...
Socket: wsastartup success execute.
Socket: Socket success execute.
Socket: establish the connection to "127.0.0.1: 52309"
Message = OK, send a message.
Message = OK, send a message.
Message = OK, send a message.
Message = OK, send a message.
Message = OK, send a message.
Message = OK, send a message.
Message = OK, send a message.
Message = OK, send a message.
Message = OK, send a message.
Message = OK, send a message.
Socket: close connection to "127.0.0.1: 52309"
Press any key to continue

Server
Socket of service is run...
Socket: wsastartup success execute.
Socket: Socket success execute.
Bind OK!
Listen OK!
Accepting...
OK, send a message.
OK, send a message.
OK, send a message.
OK, send a message.
OK, send a message.
OK, send a message.
OK, send a message.
OK, send a message.
OK, send a message.
OK, send a message.
Qk, send a message.
Press any key to continue

That's it. The socket-related content is far more than that. I am here to give you a reference and want to learn more? The road is still long. For detailed implementation code, go to my "source code" and choose not here to Reduce the length.

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.