Analyze the socket-related functions in TI's demo
[Copy link]
The function content of this part is from the simple link api provided by TI, and some of my own understanding is added. If there are any errors, please help point them out.
2.1 Socket establishment
To establish a socket connection, the program can call the sl_socket function, which returns a handle similar to a file descriptor. The prototype of the sl_socket function is: _i16 sl_socket(_i16 Domain,_i16 Type,_i16 Protocol);Domain indicates the protocol family used, usually PF_INET, (which is the same as AF_INET in addrinfo now.) represents the Internet protocol family (TCP/IP protocol family); Type parameter specifies the type of socket: SOCK_STREAM or SOCK_DGRAM; Protocol is usually assigned 0. The sl_socket() call returns an integer socket descriptor, which you can use in subsequent calls. The socket descriptor is a pointer to an internal data structure, which points to the entry of the descriptor table. When calling the socket function, the socket execution body will establish a socket. Actually, "establishing a socket" means allocating storage space for a socket data structure. The structure contains five types of information: communication protocol, local protocol address, local host port, remote host address, and remote protocol port. This is the necessary information for two network programs to establish a connection in a network connection.
2.2 Socket Configuration
After a socket descriptor is returned by the sl_socket call, the socket is configured before using the socket for network transmission. The connection-oriented socket client saves local and remote information in the socket data structure by calling the sl_Connect function. The client and server of the connectionless socket and the server of the connection-oriented socket configure local information by calling the sl_Bind function.
The sl_bind function associates a socket with a port on the local machine, and then you can listen for service requests on that port. The prototype of the bind function is: _i16 sl_Bind(_i16 sd,const SlSockAddr *addr,_i16addrlen); sd is the socket descriptor returned by calling the sl_socket function, addr is a pointer to the sockaddr type that contains information such as the local IP address and port number; addrlen is often set to sizeof(struct sockaddr). The structure types used in this function are:
struct SlSockAddr {
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 with 0 to keep the same size as struct sockaddr*/
}; When using the bind function, you can use the following assignment to automatically obtain the local IP address and randomly obtain an unoccupied port number:
my_addr.sin_port = 0; /* The system randomly selects an unused port number*/
my_addr.sin_addr.s_addr = INADDR_ANY; /* Fill in the local IP address*/
By setting my_addr.sin_port to 0, the function will automatically select an unused port for you to use. Similarly, by setting my_addr.sin_addr.s_addr to INADDR_ANY, the system will automatically fill in the local IP address. The sl_Bind() function returns 0 when successfully called; it returns "-1" when an error occurs.
2.3 Connection Establishment
The connection-oriented client program uses the sl_connect function to configure the socket and establish a TCP connection with the remote server. Its function prototype is: _i16 sl_connect(_i16 sd,SlSockAddr *serv_addr,_i16 addrlen); sd is the socket descriptor returned by the socket function; serv_addr is a pointer containing the remote host IP address and port number; addrlen is the length of the remote geological structure. The connect function returns -1 when an error occurs. There is no need to call sl_bind() for client programming, because in this case you only need to know the IP address of the destination machine, and you don't need to care which port the client uses to establish a connection with the server. The socket executor automatically selects an unoccupied port for your program and notifies your program when data arrives at the port.
The sl_connect function starts a direct connection with a remote host. Only when a connection-oriented client program uses a socket does it need to connect the socket to the remote host. Connectionless protocols never establish direct connections. Connection-oriented servers also never start a connection, they just passively listen for client requests on the protocol port.
The sl_listen function puts the socket in passive listening mode and creates an input data queue for the socket, saving the arriving service requests in this queue until the program processes them. _i16 listen(_i16 sd, _i16 backlog); sd 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 will wait in the queue for sl_accept() to accept them. If a service request arrives and the input queue is full, the socket will reject the connection request and the client will receive an error message. The sl_listen function returns -1 when an error occurs.
The sl_accept() function allows the server to receive the client's connection request. After establishing the input queue, the server calls the sl_accept function, then sleeps and waits for the client's connection request.
int accept(_i16 sd, SlSockAddr*addr, SlSocklen*addrlen);sd is the socket descriptor being monitored, addr is usually a pointer to the SlSockAddr variable, which is used to store the information of the host that makes the connection request service; addrten is usually an integer pointer variable pointing to the value of sizeof(structSlSockAddr). The accept function returns -1 if an error occurs.
First, when the socket monitored by the sl_accept function receives a connection request, the socket executor will establish a new socket, and the executor will associate this new socket with the address of the process requesting the connection. The initial socket that receives the service request can continue to listen on the previous socket and perform data transmission operations on the new socket descriptor.
2.4 Data transmission
sl_send() and sl_recv() are used to transmit data on connection-oriented sockets. The prototype of send() function is: _i16 sl_send(_i16 sd, void *msg, _i16 len,_i16 flags); sd 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 is usually set to 0. sl_send() function returns the number of bytes actually sent.
The prototype of the recv() function is: _i16 recv(_i16 sd,void *buf,_i16 len,_i16 flags);
sd is the socket descriptor for receiving data; buf is the buffer for storing received data; len is the length of the buffer. flags is also set to 0. recv() returns the number of bytes actually received, and -1 when an error occurs. sendto() and recvfrom() are used to transmit data in connectionless datagram socket mode. They are mainly used for UDP protocol, which is not used in this project, so I won't explain it. If you are interested, you can directly check the manual.
|