UC growth path 13

Review:
UC growth path 1
UC growth path 2
UC growth path 3
UC growth path 4
UC growth path 5
UC growth path 6
UC growth path 7
UC growth path 8
UC growth path 9
UC growth path 10
UC growth path 11
UC growth path 12

1, Network programming model and Implementation Based on TCP

  • There are two types of transport layer: TCP and UDP

  • TCP is connection oriented, reliable and secure, but inefficient

  • UDP is packet oriented, unreliable, but efficient

  • Establish TCP connection and disconnect: the process of establishing a connection is called the famous three handshakes and four waves when disconnected

  • Server programming model

	//1. Create a socket endpoint and return a file descriptor. lfd
	socket(2)
	//2. Bind the lfd to the ip address and port number of the server
	bind(2)
	//3. Set lfd to passive connection mode to monitor the arrival of client connection. The arrival of a client connection is put into the pending connection queue
	listen(2)
	//4. Take a client connection from the undecided connection queue and return the file descriptor of the client connection. Use this file descriptor to communicate with the client. There is no data in the pending connection queue, blocking waiting for the client's connection to arrive
	accept(2)
	while(1){
		//5 get data from client
		read()
		//6. Process the acquired data
		//7. Send the processing result back to the client
		write()
		//8. Close this connection
		close()
	}
  • Programming model of client
	//1. Create a communication endpoint and return a file descriptor
	socket(2)
	//2. Use this file descriptor to initiate a connection to the server
	connect(2)
	//3. Send message to server
	write()
	//4. Wait for the corresponding message from the server
	read()
	//5. Process the corresponding messages of the server
	//6. Close the connection with the server and overnight communication
	close()
  • socket(2)
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
//Function: create a communication endpoint and return a file descriptor
//parameter
//domain: 
//1)AF_INET             IPv4 Internet protocols          ip(7)
//2)AF_INET6            IPv6 Internet protocols          ipv6(7)
//...
//type
//1)SOCK_STREAM:TCP
//2)SOCK_DGRAM:UDP
//...
//protocol:0
//Return value: successfully return a file descriptor for the new socket; The error returns - 1, and errno is set
  • bind(2)
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
//Function: bind a name to the socket
//Parameters:
//sockfd: Specifies the specific socket (like the SIM card slot of the mobile phone)
//addr: Specifies the address and port number of the server (like SIM card)
//addrlen: Specifies the effective space size of addr
//Return value: 0 is returned successfully; The error returns - 1, and error is set

struct sockaddr {
      sa_family_t sa_family;
      char  sa_data[14];
};
  • listenl(2)
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int listen(int sockfd, int backlog);
//Function: establish a connection on the specified socket
//Parameters:
//Sockfd: return value of socket (2)
//backlog: Specifies the maximum length of the pending connection queue
//Return value: 0 is returned successfully; The error returns - 1, and error is set
  • accept(2)
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
//Function: receive connections on the specified socket
//Parameters:
//sockfd: socket(2) is specified. Return value of socket(2)
//Addr: if addr is NULL, addrlen should also be set to NULL;
//The address space specified by addr is filled with the contents of the address family of the client
//addrlen: value - result parameter, which specifies the effective space size of addr
//Return value: error returns - 1, errno is set; A nonnegative integer and a file descriptor are returned successfully,
//And the connection descriptor of the client, and use this connection descriptor to communicate with the client.
  • connect(2)
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
//Function: initiate a connection on a socket and connect the socket to the address pointed to by addr
//Parameters:
//sockfd: socket specified
//addr: address specified
//addrlen: Specifies the size of addr space
//Return value: 0 is returned successfully; The error returns - 1, and errno is set
  • IPV4 family, IPV6 family
  • Universal family struct sockaddr
struct sockaddr {
      sa_family_t sa_family;
      char  sa_data[14];
};
  • IPV4 family address, which can be viewed using man 7 ip
struct sockaddr_in {
       sa_family_t  sin_family; /* address family: AF_INET */
       in_port_t    sin_port;   /* port in network byte order */
       struct in_addr sin_addr;   /* internet address */
};

/* Internet address. */
struct in_addr {
        uint32_t   s_addr;     /* address in network byte order */
};
  • Configure port number and ip address
  • Conversion between network byte order and host byte order, htonl(3)
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
//h:host
//n:net
//s:short
//l:long
//to
  • ip address conversion: string and unsigned long integer conversion, inet_pton(3), inet_ntop(3)
#include <arpa/inet.h>
int inet_pton(int af, const char *src, void *dst);
//Function: Text -- > binary
//Parameters:
//af:AF_INET or AF_INET6
//src: ip in string format, to be converted
//dst: store the converted results
//Return value: 1 if successful; If af is invalid, return - 1 and errno is set; src invalid return 0

#include <arpa/inet.h>
const char *inet_ntop(int af, const void *src,
              		char *dst, socklen_t size);
//Function: binary - > text
//Parameters:
//af:AF_INET or AF_INET6
//src:ip address (binary)
//dst: the converted ip address (text) is stored in the space specified by this address
//size: Specifies the number of bytes available for dst buffer
//Return value: error returns NULL, and errno is set; The address pointed to by dst is returned successfully, and the converted result is stored in this space       		

eg: write server-side and client-side programs based on TCP

  • The server side is responsible for converting the string sent by the client to uppercase, server c
  • The client is responsible for sending the string to the server, and then outputting the string converted by the server to the display, client c
    • server.c
#include <stdio.h>
#include <sys/types.h>     
#include <sys/socket.h>
#include <ctype.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(void)
{
    struct sockaddr_in serv;
    int cfd;//connect fd
    char buf[128];
    //Create a socket and return the file descriptor ldf of the socket
    int lfd = socket(AF_INET, SOCK_STREAM, 0); 
    if(lfd==-1){
        perror("socket");
        return -1; 
    }   
    //Initialize members of serv
    serv.sin_family=AF_INET;
    serv.sin_port=htons(1024);
    //INADDR_ANY stands for all ip addresses of this machine
    serv.sin_addr.s_addr=htonl(INADDR_ANY);
    //Bind the lfd to the local ip address and port
    int b = bind(lfd, (struct sockaddr *)&serv, sizeof(serv));
    if(b==-1){
        perror("bind");
        return -1; 
    }   
    //Set lfd to passive link mode to monitor the arrival of client connection. If a client's connection arrives, put the connection into the pending connection queue
    listen(lfd, 5); 
    while(1){
        //Take the first connection from the undecided connection queue for processing. If there is no pending connection, block and wait. If there is, return a file descriptor
        cfd = accept(lfd, NULL, NULL);
        if(cfd==-1){
            perror("accept");
            return -1; 
        }
        //At this time, the three handshakes have been completed and the data processing is complete
        //Read client requests
        int r = read(cfd, buf, 128);
        int i;
        //Processing client requests
        for(i=0; i<r; i++){
            buf[i]=toupper(buf[i]);//Convert characters to uppercase
        }
        //Respond to the client and respond the processing information to the client
        write(cfd, buf, r); 
        //Close the connection with the client and end the connection
        close(cfd);
    }   
    return 0;
}
  • client.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(void)
{
    struct sockaddr_in serv;//ip address and port number of the server
    char *msg = "this is a test...\n";
    char buf[128];
    //Create a socket and return the file description of the socket
    int lfd = socket(AF_INET, SOCK_STREAM, 0);
    if(lfd==-1){
        perror("socket");
        return -1;
    }
    //Initialize the ip address and port number of the server
    serv.sin_family=AF_INET;//IPV4
    serv.sin_port=htons(1024);
    //ip address of the server, 127.0.0.1, text -- > binary
    inet_pton(AF_INET, "127.0.0.1", &serv.sin_addr);
    //Use lfd to initiate a connection to the server. If this function is executed successfully, three handshakes are successful
    int conn=connect(lfd, (struct sockaddr*)&serv, sizeof(serv));
    if(conn){
        perror("connect");
        return -1;
    }
    //Send string to server
    write(lfd, msg, strlen(msg));
    //Wait for the response information of the server. If there is no response, block the waiting
    int r=read(lfd, buf, 128);
    //Output the acquired response information to the display
    write(1, buf, r);
    //Close the connection with the server and end communication
    close(lfd);
    return 0;
}

  • Improve eg
    server.c
#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <ctype.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(void)
{
    struct sockaddr_in serv, clie;
    int cfd;//connect fd
    char buf[128];
    //Create a socket and return the file descriptor ldf of the socket
    int lfd = socket(AF_INET, SOCK_STREAM, 0); 
    if(lfd==-1){
        perror("socket");
        return -1; 
    }   
    //Initialize members of serv
    serv.sin_family=AF_INET;
    serv.sin_port=htons(1024);
    //INADDR_ANY stands for all ip addresses of this machine
    serv.sin_addr.s_addr=htonl(INADDR_ANY);
    //Bind the lfd to the local ip address and port
    int b = bind(lfd, (struct sockaddr *)&serv, sizeof(serv));
    if(b==-1){
        perror("bind");
        return -1; 
    }   
    //Set lfd to passive link mode to monitor the arrival of client connection. If a client's connection arrives, put the connection into the pending connection queue
    listen(lfd, 5); 
    while(1){
        socklen_t cli_len = sizeof(clie);
        //Take the first connection from the undecided connection queue for processing. If there is no pending connection, block and wait. If there is, return a file descriptor
        cfd = accept(lfd, (struct sockaddr *)&clie, &cli_len);
        if(cfd==-1){
            perror("accept");
            return -1; 
        }
        char IP[64];
        //binary-->text
        printf("%s\n", inet_ntop(AF_INET, &clie.sin_addr, IP, 64));
        //At this time, the three handshakes have been completed and the data processing is complete
        //Read client requests
        int r = read(cfd, buf, 128);
        int i;
        //Processing client requests
        for(i=0; i<r; i++){
            buf[i]=toupper(buf[i]);//Convert characters to uppercase
        }
        //Respond to the client and respond the processing information to the client
        write(cfd, buf, r); 
        //Close the connection with the client and end the connection
        close(cfd);
    }   
    return 0;
}

client.c

        perror("connect");
        return -1; 
    }   
    //Send string to server
    write(lfd, msg, strlen(msg));
    //Wait for the response information of the server. If there is no response, block the waiting
    int r=read(lfd, buf, 128);
    //Output the acquired response information to the display
    write(1, buf, r); 
    //Close the connection with the server and end communication
    close(lfd);
    return 0;
}

  • Package eg
    t_net.h
#ifndef T_NET_H_
#define T_NET_H_

/*include file*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

/*Declaration of type*/
typedef struct sockaddr_in SA4;
typedef struct sockaddr SA; 

/*Function, create a socket, and bind the returned descriptor to the local address*/
int socket_b(int port);
int trans(int fd);//Business processing of client

#endif

t_net.c

#include <stdio.h>
#include "t_net.h"

int socket_b(int port)
{
    SA4 serv;
    //Create a socket and return the file descriptor ldf of the socket
    int lfd = socket(AF_INET, SOCK_STREAM, 0); 
    if(lfd==-1){
        perror("socket");
        return -1; 
    }   
    //Initialize members of serv
    serv.sin_family=AF_INET;
    serv.sin_port=htons(port);
    //INADDR_ANY represents all ip addresses of the machine
    serv.sin_addr.s_addr=htonl(INADDR_ANY);
    //Bind the lfd to the local ip address and port
    int b = bind(lfd, (SA *)&serv, sizeof(serv));
    if(b==-1){
        perror("bind");
        return -1; 
    }   
    return lfd;
}

//Business processing
int trans(int fd) 
{
    char buf[128];
    //Read client requests
    int r=read(fd,buf,128);
    int i;
    //Processing client requests
    for(i=0;i<r;i++){
        buf[i]=toupper(buf[i]);//Convert characters to uppercase
    }   
    write(fd, buf, r); 
    return 0;
}

serverp.c

#include <stdio.h>
#include <unistd.h>
#include "t_net.h"

int main(void)
{
    SA4 clie;
    int cfd;//connect fd
    int lfd=socket_b(1024);
    if(lfd==-1) return -1; 
    //Set lfd to passive link mode to monitor the arrival of client connection. If a client's connection arrives, put the connection into the pending connection queue
    listen(lfd, 5); 
    while(1){
        socklen_t cli_len = sizeof(clie);
        //Take the first connection from the undecided connection queue for processing. If there is no pending connection, block and wait. If there is, return a file descriptor
        cfd = accept(lfd, (SA *)&clie, &cli_len);
        if(cfd==-1){
            perror("accept");
            return -1; 
        }
        char IP[64];
        //binary-->text
        printf("%s\n", inet_ntop(AF_INET, &clie.sin_addr, IP, 64));
        //At this time, the three handshakes have been completed and the data processing is complete
        trans(cfd);//Business processing
        //Close the connection with the client and end the connection
        close(cfd);
    }   
    return 0;
}

client.c

    inet_pton(AF_INET, argv[1], &serv.sin_addr);
    //Use lfd to initiate a connection to the server. If this function is executed successfully, three handshakes are successful
    int conn=connect(lfd, (SA *)&serv, sizeof(serv));
    if(conn==-1){
        perror("connect");
        return -1; 
    }   
    //Send string to server
    write(lfd, msg, strlen(msg));
    //Wait for the response information of the server. If there is no response, block the waiting
    int r=read(lfd, buf, 128);
    //Output the acquired response information to the display
    write(1, buf, r); 
    //Close the connection with the server and end communication
    close(lfd);
    return 0;
}
  • eg: the client and server connect at one time and transmit multiple strings. If the client wants to end the connection, enter exit.
    t_net.h
#ifndef T_NET_H_
#define T_NET_H_

/*include file*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

/*Declaration of type*/
typedef struct sockaddr_in SA4;
typedef struct sockaddr SA; 

/*Function, create a socket, and bind the returned descriptor to the local address*/
int socket_b(int port);
int trans(int fd);//Business processing of client

#endif

t_net.c

#include <stdio.h>
#include <string.h>
#include "t_net.h"

int socket_b(int port)
{
    SA4 serv;
    //Create a socket and return the file descriptor ldf of the socket
    int lfd = socket(AF_INET, SOCK_STREAM, 0); 
    if(lfd==-1){
        perror("socket");
        return -1; 
    }   
    //Initialize members of serv
    serv.sin_family=AF_INET;
    serv.sin_port=htons(port);
    //INADDR_ANY stands for all ip addresses of this machine
    serv.sin_addr.s_addr=htonl(INADDR_ANY);
    //Bind the lfd to the local ip address and port
    int b = bind(lfd, (SA *)&serv, sizeof(serv));
    if(b==-1){
        perror("bind");
        return -1; 
    }   
    return lfd;
}

//Business processing
int trans(int fd) 
{
    char buf[128];
    while(1){
        memset(buf, 0, 128);
        //Read client requests
        int r=read(fd,buf,128);
        int i;
        //Processing client requests
        for(i=0;i<r;i++){
            buf[i]=toupper(buf[i]);//Convert characters to uppercase
        }
        write(fd, buf, r); 
        if(strcmp(buf,"EXIT")==0) break;
    }   
    return 0;
}

serverp.c

#include <stdio.h>
#include <unistd.h>
#include "t_net.h"

int main(void)
{
    SA4 clie;
    int cfd;//connect fd
    int lfd=socket_b(1024);
    if(lfd==-1) return -1; 
    //Set lfd to passive link mode to monitor the arrival of client connection. If a client's connection arrives, put the connection into the pending connection queue
    listen(lfd, 5); 
    while(1){
        socklen_t cli_len = sizeof(clie);
        //Take the first connection from the undecided connection queue for processing. If there is no pending connection, block and wait. If there is, return a file descriptor
        cfd = accept(lfd, (SA *)&clie, &cli_len);
        if(cfd==-1){
            perror("accept");
            return -1; 
        }
        char IP[64];
        //binary-->text
        printf("%s\n", inet_ntop(AF_INET, &clie.sin_addr, IP, 64));
        //At this time, the three handshakes have been completed and the data processing is complete
        trans(cfd);//Business processing
        //Close the connection with the client and end the connection
        close(cfd);
    }   
    return 0;
}

clientp.c

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "t_net.h"

int main(int argc, char* argv[])
{
    SA4 serv;//ip address and port number of the server
    char buf[128];
    char msg[128];
    //Create a socket and return the file description of the socket
    int lfd = socket(AF_INET, SOCK_STREAM, 0); 
    if(lfd==-1){
        perror("socket");
        return -1; 
    }   
    //Initialize the ip address and port number of the server
    serv.sin_family=AF_INET;//IPV4
    serv.sin_port=htons(1024);
    //ip address of the server, 127.0.0.1, text -- > binary
    inet_pton(AF_INET, argv[1], &serv.sin_addr);
    //Use lfd to initiate a connection to the server. If this function is executed successfully, three handshakes are successful
    int conn=connect(lfd, (SA *)&serv, sizeof(serv));
    if(conn==-1){
        perror("connect");
        return -1; 
    }   
    while(gets(msg)){
    
        //Send string to server
        write(lfd, msg, strlen(msg));
        memset(buf, 0, 128);
        //Wait for the response information of the server. If there is no response, block the waiting
        int r=read(lfd, buf, 128);
        if(strcmp(buf,"EXIT")==0) break;
        //Output the acquired response information to the display
        write(1, buf, r); 
        printf("\n");
    }   
    //Close the connection with the server and end communication
    close(lfd);
    return 0;
}

2, Implementation of concurrent server

  • Implementation of Concurrency: multiplexing, threads, processes
  • Parent process
    • Take a connection from the undecided connection queue
    • Create child process
    • Close the connection descriptor of the client
    • Reclaim the resources of the child process, waitpid()
  • Subprocess
    • close(lfd)
    • Handle the specific business of the client
    • close(cfd)
    • exit(0)

eg: Code of concurrent server
t_net.h

#ifndef T_NET_H_
#define T_NET_H_

/*include file*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

/*Declaration of type*/
typedef struct sockaddr_in SA4;
typedef struct sockaddr SA; 

/*Function, create a socket, and bind the returned descriptor to the local address*/
int socket_b(int port);
int trans(int fd);//Business processing of client

#endif

t_net.c

#include <stdio.h>
#include <string.h>
#include "t_net.h"

int socket_b(int port)
{
    SA4 serv;
    //Create a socket and return the file descriptor ldf of the socket
    int lfd = socket(AF_INET, SOCK_STREAM, 0);
    if(lfd==-1){
        perror("socket");
        return -1;
    }
    //Initialize members of serv
    serv.sin_family=AF_INET;
    serv.sin_port=htons(port);
    //INADDR_ANY stands for all ip addresses of this machine
    serv.sin_addr.s_addr=htonl(INADDR_ANY);
    //Bind the lfd to the local ip address and port
    int b = bind(lfd, (SA *)&serv, sizeof(serv));
    if(b==-1){
        perror("bind");
        return -1;
    }
    return lfd;
}

//Business processing
int trans(int fd)
{
    char buf[128];
    while(1){
        memset(buf, 0, 128);
        //Read client requests
        int r=read(fd,buf,128);
        int i;
        //Processing client requests
        for(i=0;i<r;i++){
            buf[i]=toupper(buf[i]);//Convert characters to uppercase
        }
        write(fd, buf, r);
        if(strcmp(buf,"EXIT")==0) break;
    }
    return 0;
}

servers.c

#include <stdio.h>
#include <unistd.h>
#include "t_net.h"
#include <stdlib.h>
#include <sys/wait.h>

int main(void)
{
    SA4 clie;
    int cfd;//connect fd
    int lfd=socket_b(1024);
    if(lfd==-1) return -1; 
    //Set lfd to passive link mode to monitor the arrival of client connection. If a client's connection arrives, put the connection into the pending connection queue
    listen(lfd, 5); 
    while(1){
        socklen_t cli_len = sizeof(clie);
        //Take the first connection from the undecided connection queue for processing. If there is no pending connection, block and wait. If there is, return a file descriptor
        cfd = accept(lfd, (SA *)&clie, &cli_len);
        if(cfd==-1){
            perror("accept");
            return -1; 
        }
        char IP[64];
        //binary-->text
        printf("%s\n", inet_ntop(AF_INET, &clie.sin_addr, IP, 64));
        //Create child process
        pid_t pid=fork();
        if(pid==-1){
            perror("fork");
            return -1; 
        }
        if(pid==0){//Tasks of child processes
            close(lfd);
            //At this time, the three handshakes have been completed and the data processing is complete
            trans(cfd);//Business processing
            //Close the connection with the client and end the connection
            close(cfd);
            exit(0);
        }
        else{//Tasks of the parent process
            close(cfd);
            //Non blocking
            waitpid(-1, NULL, WNOHANG);
        }
    }   
    return 0;
}

clientp.c

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "t_net.h"

int main(int argc, char* argv[])
{
    SA4 serv;//ip address and port number of the server
    char buf[128];
    char msg[128];
    //Create a socket and return the file description of the socket
    int lfd = socket(AF_INET, SOCK_STREAM, 0); 
    if(lfd==-1){
        perror("socket");
        return -1; 
    }   
    //Initialize the ip address and port number of the server
    serv.sin_family=AF_INET;//IPV4
    serv.sin_port=htons(1024);
    //ip address of the server, 127.0.0.1, text -- > binary
    inet_pton(AF_INET, argv[1], &serv.sin_addr);
    //Use lfd to initiate a connection to the server. If this function is executed successfully, three handshakes are successful
    int conn=connect(lfd, (SA *)&serv, sizeof(serv));
    if(conn==-1){
        perror("connect");
        return -1; 
    }   
    while(gets(msg)){
    
        //Send string to server
        write(lfd, msg, strlen(msg));
        memset(buf, 0, 128);
        //Wait for the response information of the server. If there is no response, block the waiting
        int r=read(lfd, buf, 128);
        if(strcmp(buf,"EXIT")==0) break;
        //Output the acquired response information to the display
        write(1, buf, r); 
        printf("\n");
    }   
    //Close the connection with the server and end communication
    close(lfd);
    return 0;
}

Supplement: setsockopt(2) solve the problem of ip address reuse (address reuse is because it needs to be implemented in the kernel state below the transport layer. The address resources just used have not been recycled, and the address reuse problem will occur if the address is reused immediately)

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int getsockopt(int sockfd, int level, int optname,
                      void *optval, socklen_t *optlen);
int setsockopt(int sockfd, int level, int optname,
                      const void *optval, socklen_t optlen);

3, UDP based programming model and its implementation

  • Using UDP for network communication, there is no need to establish a connection at all
  • Model
//Server:
//1. Create a socket communication endpoint
//2. Bind the socket to the local address
while(1){
	 //3. Use recvfrom blocking to wait for the arrival of client data
	 //4. Process the data obtained from the client
	 //5. Respond the result to the client
} 

//client:
//1. Create a socket
//2. Use this socket to send messages to the server
//3. Block the response message waiting for the server
//4. Process response message
//5. Close the socket and end the process of the client
  • sendto(2) \ recvfrom(2)
#include <sys/types.h>
#include <sys/socket.h>
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
              const struct sockaddr *dest_addr, socklen_t addrlen);
//Function: Send a message on socket
//parameter
//sockfd: Specifies the socket on which to send messages
//buf: Specifies the address where the data to be sent is stored
//len: length of data to be sent
//flags:0 (see man help for others)
//dest_addr: the destination address is specified
//addrlen: dest specified_ Address space size pointed to by addr
//Return value: successfully returns the number of bytes sent; The error returns - 1, and errno is set

#include <sys/types.h>
#include <sys/socket.h>
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                struct sockaddr *src_addr, socklen_t *addrlen);
//Function: receive a message from socket
//parameter
//sockfd: Specifies the socket on which to receive messages
//buf: Specifies the address. Use this address to start storing messages
//len: Specifies the size of the buf space
//flags:0 (see man help for others)
//src_addr: fill the content of the client's address family in the specified address space
//addrlen: value - result parameter, which specifies the effective space size of addr
//Return value: successfully returns the number of bytes received; Error returned - 1

eg: programming the server and client of UDP communication

userver.c

#include <stdio.h>
#include "t_net.h"
#include <ctype.h>

int main(void)
{
    SA4 serv, clie;
    char buf[128];
    socklen_t cli_len;
    //Create udp based socket
    int fd=socket(AF_INET, SOCK_DGRAM, 0); 
    if(fd==-1){
        perror("socket");
        return -1; 
    }   
    //Initialize the ip address and port number of the server
    serv.sin_family=AF_INET;
    serv.sin_port=htons(4000);
    serv.sin_addr.s_addr=htonl(INADDR_ANY);
    //Bind fd to the local ip address and port number
    int b=bind(fd, (SA *)&serv, sizeof(serv));
    if(b==-1){
        perror("bind");
        return -1; 
    }   
    while(1){
        cli_len=sizeof(SA4);
        //Get data from client
        int rcv=recvfrom(fd, buf, 128, 0, (SA *)&clie, &cli_len);
        if(rcv==-1){
            perror("recvfrom");
            return -1; 
        }
        int i;
        for(i=0; i<rcv; i++){
            buf[i]=toupper(buf[i]);    
        }
        //Send the processing result to the client
        int s=sendto(fd, buf, rcv, 0, (SA *)&clie, sizeof(SA4));
        if(s==-1){
            perror("sendto");
            return -1; 
        }
    }   
    return 0;
}

uclient.c

#include <stdio.h>
#include "t_net.h"
#include <string.h>
#include <unistd.h>

int main(int argc, char* argv[])
{
    char *msg="this is a test...\n";
    SA4 serv;
    char buf[128];
    //Create a socket based on udp
    int fd=socket(AF_INET, SOCK_DGRAM, 0); 
    if(fd==-1){
        perror("socket");
        return -1; 
    }   
    //Initialize the ip address and port number of the server
    serv.sin_family=AF_INET;
    serv.sin_port=htons(4000);
    inet_pton(AF_INET, argv[1], &serv.sin_addr);
    //Send message to server
    int s=sendto(fd,msg,strlen(msg),0,(SA *)&serv,sizeof(SA4));
    if(s==-1){
        perror("sendto");
        return -1; 
    }   
    //Blocking waiting for response messages from the server
    int rcv=recvfrom(fd,buf,128,0,NULL,NULL);
    if(rcv==-1){
        perror("recvfrom");
        return -1; 
    }   
    //Output the response message of the server to the display
    write(1, buf, rcv);
    return 0;
}

Keywords: network socket udp TCPIP

Added by mshen on Fri, 18 Feb 2022 23:59:09 +0200