Linux network Programming (2)--implementation of the basic server with TCP __HTML5

Source: Internet
Author: User
Tags htons

A basic c/s server model is simple: Client <------------------------> server

In short, the client and the server between the call, the way the general use of TCP and UDP two.

TCP and UDP differences

1, TCP provides the connection between the client and the server. The TCP client first establishes a connection with a given server, then exchanges data across that server, and then terminates the connection.

(The connection is actually a negotiation mechanism, predefined some of the state variables, tell each other such as serial number and notification window size status information)

2, TCP provides a reliable transmission mechanism, do not need to be like UDP as required through the application layer to achieve reliability, directly through the protocol to achieve. Send data after waiting for the other side to confirm, not receive confirmation to continue retransmission and wait, several times after the failure will give up.

3, TCP provides traffic control, TCP always tells the right end at any time it can receive from the End-to-end number of bytes of data.


A basic program model for TCP connections with sockets

is through this function of the socket to encapsulate the data, to achieve the server amount of client communication

Client Service Side

Sokcket socket ()//Create socket Descriptor

Bind ()//Bind the server address and the corresponding socket descriptor

Listen ()///Converts an active socket to a listening socket that accepts requests from the client

Connect () <-------------> Accept ()//connect () Client connection request, Accpet () function resolves listening client information.

Write ()------------> read ()/network read/write IO

Read () <--------------write ()

Close ()------------> read ()

Close ()//close closes the connection


function Interface

1, Socket

#include <sys/types.h>
#include <sys/socket.h>
int socket (int domain, int type, int protocol);
If a nonnegative descriptor is returned successfully, return 1 if error

Domain network type (typically default to Af_inet Internet), type socket types (generally default to Sock_stream), protocol protocol number

2, connect

#include <sys/socket.h>
int connect (int sockfd, struct sockaddr *serv_addr, int addrlen);
If successful return 0, if error return-1

The Connect function attempts to establish an Internet connection to a SERV_ADDR server with a socket address, addrlen default to sizeof (SOCKADDR_IN)

3. Bind

#include <sys/socket.h>
int bind (int sockfd, struct sockaddr *my_addr, int addrlen)
If a successful return of 0, if error return-1
Connect the server address to the socket

4, listen

#include <sys/socket.h>
int listen (int sockfd, int backlog);
If successful return 0, if error return-1

Tells the kernel that this is a socket created by the server, not a client, that converts the active state to a passive state.

5, accept

#include <sys/socket.h>
int accept (int listenfd, struct sockaddr *addr, int *addrlen);
If successful return 0, if error return-1 

Waits for a connection request from the client to arrive at the listener descriptor LISTENFD, then fills in the client's socket address in addr and returns a connected descriptor that can be used to communicate with the client using UNIX I/O functions.

Socket address Structure Body

<netinet/in.h>
struct in_addr{
    in_addr_t s_addr;            32bit IPv4 address
}

struct sockaddr_in{
    uint8_t;                          
    sa_family_t sin_family;           Af_inet
    in_port_t sin_port;               Port
    struct in_addr sin_addr;
    Char sin_zero[8];                Not used
};

DNS host entry structure body

Retrieves any host entries from the DNS database by calling the gethostbyname and GETHOSTBYADDR functions.

<pre name= "code" class= "CPP" > #include <netdb.h>
struct hostent{char *h_name;//host domain char **h_aliases; int h_addrtype;//host address int h_length; char **h_addr_list;
};
struct hostent* gethostbyname (const char* name);
struct hostent* gethostbyaddr (const char* addr, int len, int domain);

Specific code implementation:

Implementation of a simple client server model, does not involve multithreading, I/O multiplexing this class

SERVER.C Service Side

#include <stdio.h> #include <sys/socket.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> #include <netinet/in.h> #include <netdb.h> #include <arpa/inet.h> #define Max_ LISTEN 1024 #define MAX_LINE 1024 int socket (int domain, int type, int protocol) {int SOCKFD = socket (domain, type, p
    ROTOCOL);
        if (SOCKFD < 0) {perror ("init socket:");
    Exit (0);
return SOCKFD; } void Bind (int sockfd, struct sockaddr *myaddr, int addrlen) {if (Bind (SOCKFD, MYADDR, Addrlen) < 0) {p
        Error ("bind");
    Exit (0);
        } void Listen (int sockfd, int backlog) {if (Listen (SOCKFD, backlog) < 0) {perror ("Listen");
    Exit (0);
    int Accept (int listenfd, struct sockaddr *addr, int *addrlen) {int clientfd = Accept (listenfd, addr, Addrlen);
        if (Clientfd < 0) {perror ("accept");
    Exit (0);
return CLIENTFD;
   } void Close (int clientfd) { if (Close (CLIENTFD) < 0) {perror (' close ');
    Exit (0); } struct hostent* gethostbyaddr (const char *addr, int len, int domain) {struct hostent* host = gethostbyaddr (addr, l
    EN, domain);
        if (NULL = = host) {perror ("host_by_addr");
    Exit (0);
} return host;
    ssize_t Read (int fd, void* buf, size_t N) {ssize_t num= Read (FD, BUF, N);
        if (n < 0) {perror ("read");
    Exit (0);
return num;
    ssize_t Write (int fd, const void* buf, size_t N) {ssize_t num = read (FD, BUF, N);
        if (n < 0) {perror ("write");
    Exit (0);
return num;
    } void Echo (LISTENFD) {ssize_t n;
    Char Write_buff[max_line];
    
    Char Read_buff[max_line];
    memset (write_buff, 0, Max_line);

    memset (read_buff, 0, Max_line);
    n = Read (LISTENFD, Read_buff, max_line);

    Read_buff[n] = ' the ';
    strcpy (Write_buff, "From server echo:"); strcpy (Write_buff+strlen ("From server Echo:"), Read_bUFF);

    
n = Write (LISTENFD, Write_buff, max_line);
    int main (int argc, char **argv) {int servfd, CLIENTFD, Port, Clientlen;
    struct sockaddr_in servaddr;
    struct sockaddr_in cliaddr;
    struct Hostent *host;
    char* hostaddr;
        if (argc!= 2) {fprintf (stderr, "usage:%s<port>\n", argv[0]);
    Exit (0);  } port = Atoi (argv[1]);
    
    Get Port servfd = Socket (af_inet, sock_stream, 0);
    Init servaddr memset (&servaddr, 0, sizeof (SERVADDR));
    memset (&cliaddr, 0, sizeof (CLIADDR));
    servaddr.sin_family = af_inet;
    SERVADDR.SIN_ADDR.S_ADDR = htonl (Inaddr_any);
    Servaddr.sin_port = htons ((unsigned short) port);
    
    Clientlen = sizeof (CLIADDR);
    Bind (servfd, (struct sockaddr*) &servaddr, sizeof (SERVADDR));

    Listen (servfd, Max_listen);
        while (1) {//init server memset (&cliaddr, 0, sizeof (CLIADDR)); CLIENTFD = Accept (servfd, (struct sockaddr*) &cliaddr, &clientlen);
        Host = gethostbyaddr ((const char*) &cliaddr.sin_addr.s_addr, sizeof (CLIADDR.SIN_ADDR.S_ADDR), af_inet);
        printf ("Server Connect to host:%s%s\n", Host->h_name, Inet_ntoa (CLIADDR.SIN_ADDR));
        Echo (CLIENTFD);
    Close (CLIENTFD); }
}

CLIENT.C Client

#include <stdio.h> #include <sys/socket.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> #include <netinet/in.h> #include <netdb.h> #define max_line 1024 int Socket (int domain, int t
    ype, int protocol) {int SOCKFD = socket (domain, type, protocol);
        if (SOCKFD < 0) {perror ("init socket");
    Exit (0);
return SOCKFD;
        } void Close (int clientfd) {if (Close (CLIENTFD) < 0) {perror (' close ');
    Exit (0); } struct hostent* gethostbyaddr (const char *addr, int len, int domain) {struct hostent* host = gethostbyaddr (addr, l
    EN, domain);
        if (NULL = = host) {perror ("host_by_addr");
    Exit (0);
} return host;
        } ssize_t Read (int fd, void* buf, size_t N) {if (read (FD, BUF, N) < 0) {perror ("read");
    Exit (0);
        } ssize_t Write (int fd, const void* buf, size_t N) {if (write (fd, BUF, N) < 0) {perror ("write"); Exit(0); } void Connect (int sockfd, struct sockaddr* serv_addr, int addrlen) {if (Connect (SOCKFD, serv_addr, Addrlen) <
        0) {perror ("connect");
    Exit (0);
    } void Message_handle (int clientfd) {size_t n;
    Char Send_buff[max_line];
    Char Recv_buff[max_line];
    memset (send_buff, 0, Max_line);

    memset (recv_buff, 0, Max_line);
    Fgets (Send_buff, Max_line, stdin);

    Send_buff[strlen (Send_buff)-1] = ';
    n = Write (clientfd, Send_buff, strlen (Send_buff) +1);

    n = Read (clientfd, Recv_buff, max_line);
printf ("%s \ n", Recv_buff);
    int main (int argc, char **argv) {int clientfd, port;
    struct sockaddr_in servaddr;
        if (argc!= 3) {fprintf (stderr, "usage:%s<addr> <port>\n", argv[0]);
    Exit (0);
    } port = Atoi (argv[2]);
    printf ("Port:%d\n", port);

    printf ("Addr:%s\n", argv[1]);

    CLIENTFD = Socket (af_inet, sock_stream, 0);
    servaddr.sin_family = af_inet; Servaddr.sin_port = Htons (port);
    Inet_pton (Af_inet, argv[1], &servaddr.sin_addr); 
    Connect (CLIENTFD, (struct sockaddr*) &servaddr, sizeof (SERVADDR));
    Message_handle (CLIENTFD);
Close (CLIENTFD); }



Code Analysis:

The server processes the client connection by the TCP model on the above figure, and whenever a client connects, the customer information is printed and the customer message is reflected back to the client after receiving the message from the client.

Run Result:

Client:



Service side:

Use the NETSTAT-A command to view the TCP connection status after the client is interrupted, 9000 port is in the listen state, and the connection is in the TIME_WAIT state



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.