A basic c/s server model is simple: Client <------------------------> server
In short, the client and the server between the call, the call is generally used in both TCP and UDP.
TCP and UDP differences
1. TCP provides a 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.
(connection is actually a negotiation mechanism, pre-defined some of the two sides of the state variables, tell each other such as the serial number and the size of the Notification window status information)
2, TCP provides a reliable transmission mechanism, do not need to be like UDP through the application layer to achieve reliability, directly through the protocol to achieve. After sending the data to wait for the other party to confirm, do not receive confirmation to continue retransmission and wait, several retransmission failed to give up.
3. TCP provides traffic control, and TCP always tells the peer how many bytes of data it can receive at any one time from the peer.
A basic program model for TCP connections using sockets
is to encapsulate the data through this function of the socket to achieve the server's client communication
Client Service side
Sokcket socket ()//Create socket Descriptor
Bind ()//Bind the server address and the corresponding socket descriptor
Listen ()//Convert an active socket to a listening socket that can accept requests from the client
Connect () <-------------> Accept ()//connect () Client connection request, Accpet () function parses the client information that is being monitored,
Write ()------------> read ()//network read/write IO
Read () <--------------write ()
Close ()------------> read ()
Close ()//close closing the connection
Function interface
1. Socket
#include <sys/types.h> #include <sys/socket.h>int sockets (int domain, int type, int protocol), or if a non-negative descriptor is successfully returned, If an error is returned-1
Domain network type (generally default to af_inet Internet), type socket types (typically default to Sock_stream), protocol protocol number
2. Connect
#include <sys/socket.h>int connect (int sockfd, struct sockaddr *serv_addr, int addrlen); returns 1 if the error returns 0
The Connect function attempts to establish an Internet connection to a server with a socket address of SERV_ADDR, Addrlen defaults to sizeof (SOCKADDR_IN)
3. Bind
#include <sys/socket.h>int bind (int sockfd, struct sockaddr *my_addr, int addrlen) returns 0 if the error returns 1
Connect the server address and socket
4, listen
#include <sys/socket.h>int Listen (int sockfd, int backlog), if successful return 0, if error returns 1
Tell the kernel that this is the socket created by the server, not the client, and convert the active state to a passive state.
5. Accept
#include <sys/socket.h>
int accept (int listenfd, struct sockaddr *addr, int *addrlen);
Waits for the connection request from the client to reach the listener descriptor LISTENFD, then fills in addr with the client's socket address and returns a connected descriptor that can be used to communicate with the client using the UNIX I/O function.
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
Retrieve any host entry 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:
Implementing a simple client server model that does not involve multithreading, I/O multiplexing such
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 1024int socket (int domain, int type, int protocol) {int SOCKFD = socket (domain, type, proto COL); 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) {perror ("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, Len, 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] = ' + '; 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 1024int Socket (int domain, int Type, 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, Len, 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); while (1{Connect (clientfd, (struct sockaddr*) &servaddr, sizeof (SERVADDR)); Message_handle (CLIENTFD); Close (CLIENTFD); }}
Code Analysis:
The server processes the client connection by the TCP model, which prints the customer information whenever a client connects, and then receives the message from the customer, reflecting the customer message back to the client.
Operation Result:
Client:
Client input wwww, return wwww, then close the connection, then connect perror error, exit (0) exit
Service side:
Use the NETSTAT-A command to view TCP connection status after a client interrupt, port 9000 is in listen state, the connection is in Time_wait state
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Network Programming (2)--implementation of basic server with TCP