Socket and TCP/UDP programming ~__ programming

Source: Internet
Author: User
Tags function prototype htons
the socket interface is a TCP/IP network API, the socket interface defines a number of functions or routines that programmers can use to develop applications on a TCP/IP network. To learn about TCP/IP network programming on the Internet, you must understand the socket interface.
The socket interface designer first placed the interface inside the UNIX operating system. If you understand the input and output of UNIX systems, you can easily understand the socket. Socket data transfer In a network is a special i/o,socket and a file descriptor. The socket also has a function call socket () that is similar to opening a file, which returns an integral socket descriptor, and subsequent connection creation, data transfer, and so on are implemented through the socket. There are two common types of sockets: Streaming Socket(Sock_stream) and Data-Quote Socket(SOCK_DGRAM). A stream is a connection-oriented socket that is applied to a connection-oriented TCP service; A datagram socket is a connectionless socket that corresponds to a connectionless UDP service application.

Socket Build
In order to establish a socket, the program can call the socket function, which returns a handle similar to a file descriptor. The socket function prototype is:
int socket (int domain, int type, int protocol);
Domain indicates the protocol family used, usually pf_inet, that represents the Internet Protocol family (TCP/IP protocol family); type parameter specifies the kind of socket: Sock_stream or SOCK_DGRAM, The socket interface also defines the original socket (SOCK_RAW), allowing the program to use low-level protocols; Protocol is usually assigned "0". The socket () call returns an integral socket descriptor that you can use later in the call.
The socket descriptor is a pointer to an internal data structure that points to the description chart entry. When you call the socket function, the socket executor creates a socket, in effect "building a socket" means allocating storage space for a socket data structure. The socket executor manages the descriptor table for you.
A network connection between two network programs includes five types of information: communication Protocol, local protocol address, local host port, remote host address, and remote protocol port. The socket data structure contains these five kinds of information.

Socket Configuration
After you return a socket descriptor through a socket call, you must configure the socket before you can use the socket for network transport. The connection-oriented socket client saves local and remote information in the socket data structure by calling the Connect function. Clients and services that do not have a connection to the socket, and the server that faces the connection socket, configure local information by calling the BIND function.
The bind function relates the socket to a port on this computer, and you can then listen for service requests on that port. The BIND function prototype is:
int bind (int sockfd, struct sockaddr *my_addr, int addrlen);
SOCKFD is the socket descriptor that calls the socket function return, MY_ADDR is a pointer to a SOCKADDR type that contains information such as native IP address and port number, and Addrlen is often set to sizeof (struct sockaddr).
The struct sockaddr struct type is used to hold the socket information:
struct sockaddr ... {
unsigned short sa_family; /**//* address Family, af_xxx * *
Char sa_data[14]; /**//* 14-BYTE protocol address * *
} ;
Sa_family is typically af_inet, representing the Internet (TCP/IP) address family, and Sa_data contains the IP address and port number of the socket.
There is another type of structure:
struct sockaddr_in ... {
short int sin_family; /**//* Address Family * *
unsigned short int sin_port; /**//* Port Number * *
struct IN_ADDR sin_addr; /**//* IP Address * *
unsigned char sin_zero[8]; /**//* fill 0 To keep the same size as struct SOCKADDR
} ;
This structure is more convenient to use. Sin_zero is used to populate the SOCKADDR_IN structure with the same length as the struct sockaddr, which can be set to zero with the bzero () or memset () function. Pointers to sockaddr_in and pointers to SOCKADDR can be converted to each other, which means that if a function requires a type of argument that is sockaddr, you can convert a pointer to a sockaddr_in to a pointer to a sockaddr when the function calls. , or vice versa.
When using the BIND function, you can use the following assignment to automatically obtain a native IP address and randomly obtain a port number that is not occupied:
My_addr.sin_port = 0; /* System randomly select an unused port number * *
MY_ADDR.SIN_ADDR.S_ADDR = Inaddr_any; /* Fill in the local IP address * *
By placing the My_addr.sin_port at 0, the function will automatically select an unused port for you to use. Similarly, by placing the my_addr.sin_addr.s_addr as Inaddr_any, the system automatically fills in the native IP address.
Note that using the BIND function is necessary to convert Sin_port and sin_addr into network byte precedence, while SIN_ADDR does not need to convert.
The computer data store has two byte precedence: High byte priority and low byte priority. data on the Internet is transmitted over the network in high byte order, so a machine that stores data internally at low byte priority needs to be converted when data is transferred over the Internet, otherwise data inconsistency occurs.
The following are several byte-order conversion functions:
htonl (): Converts a 32-bit value from host byte sequence to network byte order
htons (): Converts a 16-bit value from host byte sequence to network byte order
Ntohl (): Converts a 32-bit value from a network byte sequence to a host byte sequence
Ntohs (): Converts a 16-bit value from a network byte sequence to a host byte sequence
The Bind () function returns 0 when it is successfully invoked, returns "-1" When an error occurs, and errno the corresponding error number. Note that when you call the BIND function, you do not typically place the port number to a value less than 1024, since 1 to 1024 is the reserved port number, and you can choose any port number greater than 1024 that is not occupied.

Connection established
Connection-oriented client programs use Connect function to configure the socket and establish a TCP connection with the remote server, its function prototype is:
int connect (int sockfd, struct sockaddr *serv_addr,int addrlen);
SOCKFD is the socket descriptor returned by the socket function; Serv_addr is a pointer to the remote host IP address and port number; The Addrlen is the length of the remote geologic structure. The Connect function returns-1 when an error occurs, and sets errno to the appropriate error code. Do client programming without invoking bind (), because in this case only need to know the destination machine's IP address, and the client through which port to establish a connection with the server does not need to care, the socket Executive Body for your program automatically select an unused port, and notify your program data when to interrupt the mouth.
   Connect function start and direct connection to remote host。 You need to connect this socket to a remote host only if you are using a socket for a connection-oriented client. A connectionless protocol never establishes a direct connection. A connection-oriented server also never initiates a connection, it simply listens to the client's request on the protocol port.
   The listen function causes the socket to be in a passive listening mode and creates an input data queue for the socket, saving the incoming service requests in this queue until the program processes them
int listen (int sockfd, int backlog);
SOCKFD is the socket descriptor returned by the socket system call; backlog Specifies the maximum number of requests allowed in the request queue, and incoming connection requests wait in the queue for accept () (refer to the following). Backlog limits the number of requests waiting for a service in the queue, and most system defaults are 20. If a service request arrives, the input queue is full, the socket rejects the connection request, and the customer receives an error message.
When an error occurs, the Listen function returns-1 and the corresponding errno error code is placed.
   Accept () function allows the server to receive client connection requests。 After the input queue is established, the server calls the Accept function and then sleeps and waits for the client's connection request.
int accept (int sockfd, void *addr, int *addrlen);
SOCKFD is a listening socket descriptor, addr is usually a pointer to a SOCKADDR_IN variable that holds information about the host that made the connection request service (a host issued the request from a port), and Addrten typically a pointing value of sizeof ( Integer pointer variable for struct sockaddr_in). When an error occurs, the Accept function returns-1 and the corresponding errno value is placed.
First, when the Accept function watches the socket receiving the connection request, the socket executor creates a new socket, the execution body connects the new socket to the address of the requesting connection process, and the initial socket that receives the service request can still continue to the previous The socket is listening, and the data can be transferred on the new socket descriptor.

data transfer
The two functions, Send () and recv (), are used for data transfer on a connection-oriented socket.
The Send () function prototype is:
int send (int sockfd, const void *msg, int len, int flags);
SOCKFD is the socket descriptor you want to use to transmit data; MSG is a pointer to the data to be sent; Len is the length of the data in bytes; Flags are typically set to 0 (the use of this parameter can refer to the Man manual).
The Send () function returns the number of bytes actually sent, possibly less than the data you want to send. You should compare the return value of Send () to the number of bytes you want to send in your program. This situation should be handled when the Send () return value does not match Len.
Char *msg = "hello!";
int Len, bytes_sent;
......
Len = strlen (msg);
Bytes_sent = Send (SOCKFD, msg,len,0);
......
The recv () function prototype is:
int recv (int sockfd,void *buf,int len,unsigned int flags);
SOCKFD is the socket descriptor that accepts data; BUF is the buffer in which the data is received; Len is the length of the buffer. The flags were also set to 0. RECV () returns the number of bytes actually received and, when an error occurs, returns-1 and resets the corresponding errno value.


Sendto () and recvfrom () are used to transmit data in a connectionless datagram socket. Since the local socket does not have a connection to the remote machine, it should refer to the address of the eyesight when sending the data.
The SendTo () function prototype is:
int sendto (int sockfd, const void *msg,int len,unsigned int flags,const struct sockaddr *to, int tolen);
This function has two more parameters than the Send () function to represent the IP address and port number information of the target machine, and Tolen is often assigned to sizeof (struct sockaddr). The Sendto function also returns the actual byte length of the data being sent or returns 1 if a Send error occurs.
The Recvfrom () function prototype is:
int recvfrom (int sockfd,void *buf,int len,unsigned int flags,struct sockaddr *from,int);
From is a struct sockaddr type variable that holds the IP address and port number of the source machine. Fromlen are often placed as sizeof (struct sockaddr). When Recvfrom () returns, the Fromlen contains the number of bytes of data actually deposited in from. The Recvfrom () function returns the number of bytes received or returns 1 when an error occurs, and the corresponding errno is placed.
If you call the Connect () function on the datagram socket, you can also use Send () and recv () for data transfer, but the socket is still a datagram socket and uses the Transport layer's UDP service. But when the data is sent or received, the kernel automatically adds the target and source address information.

End Transmission
When all the data operations are over, you cancall the Close () function to release the socketTo stop any data operations on the socket:
Close (SOCKFD);
You can also call the shutdown () function to close the socket. This function allows you to stop data transfers only in one direction, while data transfer in a single direction continues. If you can close the write operation of a socket and allow to continue to accept data on the socket until all data is read.
int shutdown (int sockfd,int how);
SOCKFD is the descriptor for the socket that needs to be closed. Parameter how allows you to select the following ways for shutdown operations:
0-------is not allowed to continue receiving data
·1-------is not allowed to continue sending data
2-------does not allow you to continue sending and receiving data.
• Call Close () if all is allowed
Shutdown returns 0 when the operation succeeds, returns 1 when an error occurs, and resets the corresponding errno.

connection-oriented socket instance
The server in the code instance sends a string to the client via a socket connection "Hello, you are connected!". As long as the server software is running on the server, client software is running on the client, and clients will receive the string.
Server Software CodeAs follows:
#i Nclude < stdio.h >
#i Nclude < stdlib.h >
#i Nclude < errno.h >
#i Nclude < string. h >
#i Nclude < sys/types.h >
#i nclude < netinet/in. h >
#i Nclude < sys/socket.h >
#i Nclude < sys/wait.h >
#define SERVPORT 3333/* Server listener port number * *
#define BACKLOG 10/* Maximum simultaneous connection requests * *
Main ()
... {
int sockfd,client_fd; /**//*SOCK_FD: Monitor SOCKET;CLIENT_FD: Data transfer Socket * *
struct sockaddr_in my_addr; /**//* Native Address information * *
struct sockaddr_in remote_addr; /**//* Client Address Information * *
if ((SOCKFD = socket (af_inet, sock_stream, 0)) = = 1) ... {
Perror ("Socket creation error. "); Exit (1);
}
My_addr.sin_family=af_inet;
My_addr.sin_port=htons (Servport);
MY_ADDR.SIN_ADDR.S_ADDR = Inaddr_any;
Bzero (& (My_addr.sin_zero), 8);
if (bind (SOCKFD, struct sockaddr *) &my_addr, sizeof (struct sockaddr))
= =-1) ... {
Perror ("Bind error.")

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.