Socket interface (socket interface) is a set of functions that are combined with UNIX I/O functions to create network applications. Socket interfaces are implemented on most modern systems, including all UNIX variants, Windows, and the Macintosh.
1. basic structure of sockets
struct SOCKADDR
This structure is used to store socket addresses.
Data definition:
1 struct 2{3short * /*/4 Char sa_data[]; /* */56 };
Sa_family in general, are "afinet".
Sa_data contains the number of addresses, ports, and sockets for some remote computers, and the data inside it is mixed together.
To deal with Struct sockaddr, the programmer builds another similar struct sockaddr_in:
struct sockaddr_in ("in" stands for "Internet")
1 structsockaddr_in2 {3 Short intsin_family;/*Internet address Family*/4Unsigned Short intSin_port;/*Port number*/5 structIN_ADDR sin_addr;/*Internet Address*/6UnsignedCharsin_zero[8];/*Tim 0 (same size as struct sockaddr)*/7};
This structure provides a convenient means to access each element in the socket address (struct SOCKADDR) structure.
2. Basic Socket Invocation
socket () function
The client and server use the socket function to create a socket descriptor.
The socket function is defined as follows:
#include <sys/types.h>
#include <sys/socket.h>
int socket (int domain, int type, int protocol);
If successful, a nonnegative descriptor is returned, and an error returns-1.
In our code, it is common to always call the socket function with such parameters:
Client = socket (af_inet, sock_stream, 0);
Among them, Af_inet shows that we are using the Internet, and sock_stream that open is a TCP socket, 0 means using the default mode.
bind () function
The bind () function helps you specify a port to use for a socket.
When you use the socket () function to get a socket descriptor, you may need to bind the socket to a port on your machine.
This step is generally required when you need to perform a port-listening listen () operation, waiting for a connection request to be accepted.
This step is not necessary if you just want to connect to a server, which is the Connect () operation.
The system invocation declarations for bind () are as follows:
#include <sys/types.h>
#include <sys/socket.h>
int bind (int sockfd, struct sockaddr *my_addr, int addrlen);
Parameter description:
SOCKFD is the socket descriptor returned by the socket () function.
MY_ADDR is a pointer to a struct SOCKADDR that contains information about your address: name, port, and IP address.
Addrlen can be set to sizeof (struct sockaddr).
Connect () function
Let's take a moment to assume that you are a telnet application. Your user commands you to create a socket descriptor. You follow the command and call the socket ().
Then, the user tells you to connect to the "166.111.69.52" port 23 (standard Telnet port)?? What should you do?
You're lucky: The Telnet app, what you're reading now is the socket's Network Connection section: Connect ().
The Connect () function is defined like this:
#include <sys/types.h>
#include <sys/socket.h>
int connect (int sockfd, struct sockaddr *serv_addr, int addrlen);
The three parameters of Connect () have the following meanings:
SOCKFD: Socket file descriptor, returned by the socket () function.
SERV_ADDR is a structure that stores the IP address and port information for a remote computer.
Addrlen should be sizeof (struct sockaddr).
Listen () function
The Listen () function is a function that waits for someone else to connect and make a system listen request. When someone connects you, you have two steps to do:
Wait for the connection request through the Listen () function, and then use the Accept () function to handle it. (The Accept () function is described below).
The Listen () function call is very simple. The function declaration is as follows:
#include <sys/socket.h>
int listen (int sockfd, int backlog);
The parameter meanings of the Listen () function are as follows:
SOCKFD is a socket descriptor that is obtained by the socket () system call.
Backlog is the maximum number of non-processed connection request queues that can be accommodated.
What does the backlog specifically mean? Each incoming request enters a queue of incoming requests, waiting for
The Listen program calls accept () (the Accept () function is described below) function to receive this connection. When the system has not yet
When calling the Accept () function, if there are many connections, the maximum number of local waits is the value of the backlog.
"In-depth understanding of computer systems" This book is generally set to a relatively large number, such as 1024.
Accept () function
The function accept () is somewhat difficult to understand. When it is called, the approximate process is the following:
L have someone trying to call connect () from far and far away to connect to a port on your machine (of course
You are already in listen ().
L His connection will be listen join the wait queue waiting for the call of the Accept () function (the maximum number of join waiting queue
The number is determined by the second parameter backlog that calls the listen () function.
L You call the Accept () function and tell him that you are ready to connect.
The Accept () function returns a new socket descriptor, which represents the connection!
Well, at this point you have two socket descriptors, and the one returned to you is the connection to the remote computer, and
The first socket descriptor is still listen () on the original port on your machine.
The new socket descriptor you get will be able to perform the send () operation and the recv () operation.
The following is the declaration of the Accept () function:
#include <sys/socket.h>
int accept (int sockfd, void *addr, int *addrlen);
The parameters of the Accept () function have the following meanings:
SOCKFD is a socket descriptor that is being listen ().
Addr is generally a pointer to a struct SOCKADDR_IN structure that stores information about a remotely connected computer (such as the IP address and port of a remote computer)
Send () , recv () function
These two functions are the most basic of the functions that communicate through a connected socket stream.
Declaration of the Send () function:
#include <sys/types.h>
#include <sys/socket.h>
int send (int sockfd, const void *msg, int len, int flags);
The parameters of send have the following meanings:
L SOCKFD is a socket descriptor that represents your connection to a remote program.
L MSG is a pointer to the address of the message you want to send.
L Len is the length of the message you want to send.
L Flags send tokens. Generally set to 0
The function recv () call is similar to send () in many ways, and the following is the declaration of the Recv () function:
#include <sys/types.h>
#include <sys/socket.h>
int recv (int sockfd, void *buf, int len, unsigned int flags);
The parameters of recv () have the following meanings:
L SOCKFD is the socket descriptor that you want to read data from.
L BUF is a pointer to the memory cache area where you can store data.
L len is the maximum size of the buffer.
L flags is a flag of the recv () function, which is generally 0 (refer to recv () for the specific other values and meanings.
Man pages).
Recv () returns the length of the data it actually receives.
sendto () and Recvfrom () functions
These two functions are used for non-connected UDP traffic. With these two functions, the data is
The transmission on any connected network has been established. Because the datagram socket is unable to connect to the remote host, think about our
What do you need to know before sending data?
That's right! is the IP address and port of the remote host!
The following is the declaration of the SendTo () function and the Recvfrom () function:
#include <sys/types.h>
#include <sys/socket.h>
int sendto (int sockfd, const void *msg, int len, unsigned int flags,
const struct SOCKADDR *to, int tolen);
As you can see, this function is basically the same as the Send () function.
L SOCKFD is a socket descriptor that represents your connection to a remote program.
L MSG is a pointer to the address of the message you want to send.
L Len is the length of the message you want to send.
L Flags send tokens. is generally set to 0. (You can view the man pages of Send for additional reference
Values and understand what each parameter means)
l to is a pointer to a struct SOCKADDR structure that contains the IP address and port of the remote host
Data.
L Tolen just indicates the size of the struct sockaddr in memory sizeof (struct sockaddr).
Like send (), sendto () returns the number of bytes it really sends (as well as Send (), which is really
The number of bytes sent may be less than the number of bytes of data you have given it. When it happens, it also returns –1,
At the same time, the global variable errno stores the error code.
Similarly, the recv () function and the recvfrom () function are basically identical.
The declaration of Recvfrom () is:
#include <sys/types.h>
-156-linux Network programming
#include <sys/socket.h>
int recvfrom (int sockfd, void *buf, int len, unsigned int flags
struct sockaddr *from, int *fromlen);
The parameters have the following meanings:
L SOCKFD is the socket descriptor that you want to read data from.
L BUF is a pointer to the memory cache area where you can store data.
L len is the maximum size of the buffer.
L flags is a flag of the recv () function, which is generally 0 (refer to recv () for the specific other values and meanings.
Man pages).
L from is a local pointer to a struct SOCKADDR structure (which contains the source IP address and the end
Number of ports).
L Fromlen is a pointer to an int data, and its size should be sizeof (struct sockaddr).
When the function returns, the data that Formlen points to is the actual size of the struct sockaddr that the form points to.
Recvfrom () returns the number of bytes it receives, and returns 1 if an error occurs.
Close () and Shutdown () functions
After the program has been transferred to the network, you need to close the connection represented by this socket descriptor. achieve this non-
It is often simple to use only the standard closed file function: Close ().
How to use:
Close (SOCKFD);
After close () is executed, the socket will not be allowed to read and write operations. Any about the socket description
The read and write characters will receive an error.
If you want to further the closure of a network socket, you can use the function shutdown ().
It allows you to do a one-way shutdown or disable it all.
The declaration of Shutdown () is:
#include <sys/socket.h>
int shutdown (int sockfd, int how);
Its parameters have the following meanings:
L SOCKFD is a socket descriptor that you want to close.
L How can I take the following values? 0 indicates that subsequent data receive operations are not allowed, 1 means that subsequent data is not allowed to be sent, and 2 means that no subsequent operations (including receiving, sending data) are allowed, as with close ()
Shutdown () If execution succeeds will return 0, if an error occurs during the call, it will return –1, full
The error code is stored in the local variable errno.
setsockopt () and GetSockOpt () functions
The socket library provided by Linux contains an error (bug). This error shows that you cannot re-enable the same port number for a socket, even after you gracefully close the socket.
For example, let's say you write a program that the server waits on a socket. It is no problem for the server to open the socket and listen on it. In any case, there are always some reasons (whether it's normal or abnormal end-of-process)
Make your program require a restart. However, after restarting you will not be able to bind it to the original port. The error code returned from the bind () system call always reports that the port you are trying to connect to is already bound by another process. Problem
Is that the Linux kernel never marks a port as unused after the end of a bound socket process. In most Linux/unix systems, the port can be reused by one process and can even be used by other processes. Bypassing in Linux
The solution to this problem is to set the options on the setsockopt () system call when the socket is open but not yet connected. SetSockOpt () invokes the SET option and getsockopt () Gets the option from the given socket.
Here is the syntax for these calls:
#include <sys/types.h>
#include <sys/socket.h>
int getsockopt (int sockfd, int level, int name, char *value, int *optlen);
int setsockopt (int sockfd, int level, int name, char *value, int *optlen);
The following is a description of the parameters of the two calls:
L SOCKFD must be an open socket.
The L level is the protocol standard used by the function (protocol levels) (the TCP/IP protocol uses IPPROTO_TCP,
Socket Standard option Utility Sol_socket).
The L name option is described in detail in the Socket Specification (man page).
L value points to the value obtained for the getsockopt () function, the address of the value set by the setsockopt () function.
The L Optlen pointer points to an integer that contains the length of the argument in bytes.
Now let's go back to the Linux bug. When you open a socket, you must also use the following code snippet
To invoke the setsockopt () function:
/* Set parameter values */
opt = 1; len = sizeof (opt);
/* Set SOCKET Properties */
SetSockOpt (Sockfd,sol_socket,so_reuseaddr,&opt,&len);
This article refers to the "in-depth understanding of computer systems" and Bo mainstream cloud month article.
UNIX network programming Handy-socket interface function