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