一。有網絡基礎的都應該知道tcp的三次握手和四次關閉的原理,大體流程以下數據庫
三次握手:安全
三次握手的目的就是客戶端和服務器創建鏈接的過程,創建鏈接的時候,客戶端是主動打開的服務器
四次關閉,就是客戶端和服務器端斷開鏈接,這時候服務器是被動的關閉網絡
這裏再也不詳解,有興趣的能夠本身googleTCP的相關知識socket
二。長連接和短連接tcp
長連接:長連接就是在TCP鏈接的基礎上能夠連續發送多個數據包,也就是發送數據包的時候長時間保持客戶端和服務端的鏈接狀態。若是雙方沒有數據要發送,那麼必須經過發送檢測包來保持鏈接狀態。ui
短連接:短連接就是在TCP鏈接的基礎上,發送一個數據包就創建一次鏈接,若是數據完以後接斷開tcp連接,這種鏈接安全性比長連接高,一半用於銀行等安全要求很高的系統。google
何時使用長連接和短鏈接?code
長連接通常用於須要操做頻繁,點對點通信,視頻直播就是使用長連接,因爲三次握手須要時間,因此爲了節省時間,對於操做頻繁使用長連接發送一次數據後不用再次創建連接。orm
數據庫的鏈接就要使用長連接,由於短鏈接會形成socket錯誤,並且頻繁鏈接也容易形成錯誤。
這裏有一個保持長連接的簡單示例:
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <resolv.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#define MAXBUF 1024 int main(int argc, char **argv) { int sockfd, len; struct sockaddr_in dest; char buffer[MAXBUF]; char heartbeat[20] = "hello server"; fd_set rfds; struct timeval tv; int retval, maxfd = -1; if (argc != 3) { printf("error! the right format should be : \ \n\t\t%s IP port\n\t eg:\t%s127.0.0.1 80\n", argv[0], argv[0]); exit(0); } if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("Socket"); exit(errno); } bzero(&dest, sizeof(dest)); dest.sin_family = AF_INET; dest.sin_port = htons(atoi(argv[2])); memset(&(dest.sin_zero), 0, 8); if (inet_aton(argv[1], (struct in_addr*)&dest.sin_addr.s_addr) == 0) { perror(argv[1]); exit(errno); } if (connect(sockfd, (struct sockaddr*)&dest, sizeof(dest)) != 0) { perror("Connect"); exit(errno); } printf("\nReady to start chatting.\n\ Direct input messages and \n\ enter to send messages to the server\n"); while (1) { FD_ZERO(&rfds); FD_SET(0, &rfds); maxfd = 0; FD_SET(sockfd, &rfds); if (sockfd > maxfd) maxfd = sockfd; tv.tv_sec = 2; tv.tv_usec = 0; retval = select(maxfd+1, &rfds, NULL, NULL, &tv); if (retval == -1) { printf("Will exit and the select is error! %s", strerror(errno)); break; } else if (retval == 0) { //printf("No message comes, no buttons, continue to wait ...\n"); len = send(sockfd, heartbeat, strlen(heartbeat), 0); if (len < 0) { printf("Message '%s' failed to send ! \ The error code is %d, error message '%s'\n", heartbeat, errno, strerror(errno)); break; } else { printf("News: %s \t send, sent a total of %d bytes!\n", heartbeat, len); } continue; } else { if (FD_ISSET(sockfd, &rfds)) { bzero(buffer, MAXBUF+1); len = recv(sockfd, buffer, MAXBUF, 0); if (len > 0) { printf("Successfully received the message: '%s',%d bytes of data\n", buffer, len); } else { if (len < 0) printf("Failed to receive the message! \ The error code is %d, error message is '%s'\n", errno, strerror(errno)); else printf("Chat to terminate!\n"); break; } } if (FD_ISSET(0, &rfds)) { bzero(buffer, MAXBUF+1); fgets(buffer, MAXBUF, stdin); if (!strncasecmp(buffer, "quit", 4)) { printf("Own request to terminate the chat!\n"); break; } len = send(sockfd, buffer, strlen(buffer)-1, 0); if (len < 0) { printf("Message '%s' failed to send ! \ The error code is %d, error message '%s'\n", buffer, errno, strerror(errno)); break; } else { printf("News: %s \t send, sent a total of %d bytes!\n", buffer, len); } } } } close(sockfd); return 0; }