運用TCP相關原理,實現一個簡單的server端和client端的數據庫交互程序,能夠將client端輸入的指令被server端解析,將返回信息又返送給client端。git
以前的簡單內存數據庫的實現:T-Tree、T*-Tree的理解與簡單內存數據庫的實現github
七層網絡模型數據庫
TCP/IP是互聯網協議簇的統稱。
TCP-transmission control protocal-傳輸控制協議
IP-Internet Protocal-因特網協議
UDP 是User Datagram Protocol 是無鏈接類型的傳輸層協議,segmentfault
socket是對TCP/IP協議的封裝,socket翻譯爲套接字,socket是一個接口/插座。
TCPIP 是Socket的一種實現,Socket並不僅有TCP/IP。瀏覽器
socket其實不止兩種。
stream socket:串流式socket。是有鏈接類型的,網頁瀏覽器所使用的 HTTP 協議是用 stream sockets 取得網頁。
datagram socket:訊息式socket。是無鏈接類型的,用於語音通訊,視頻傳輸較多。網絡
#include <sys/types.h> #include <sys/socket.h> int socket(int domain, int type, int protocol);
一個地址描述。目前僅支持AF_INET格式,也就是說ARPA Internet地址格式。dom
指定socket類型。新套接口的類型描述類型,如TCP(SOCK_STREAM)和UDP(SOCK_DGRAM)。經常使用的socket類型有,SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等等。socket
指定協議。套接口所用的協議。如不想指定,可用0。經常使用的協議有,IPPROTO_TCP、IPPROTO_UDP、IPPROTO_STCP、IPPROTO_TIPC等,它們分別對應TCP傳輸協議、UDP傳輸協議、STCP傳輸協議、TIPC傳輸協議。tcp
#include <sys/types.h> #include <sys/socket.h> int bind(int sockfd, struct sockaddr *my_addr, int addrlen);
bind()將一本地地址與一socket捆綁.ide
sockfd 是 socket() 傳回的 socket file descriptor。
my_addr是指向包含你的地址資料丶名稱及 IP address 的 struct sockaddr 之指針。
addrlen 是以 byte 爲單位的地址長度。
#include <sys/types.h> #include <sys/socket.h> int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
connect()從client端鏈接到server端
int listen(int sockfd, int backlog); ----------------------------------------------------------------- #include <sys/types.h> #include <sys/socket.h> int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
int send(int sockfd, const void *msg, int len, int flags); ------------------------------------------------------------ int recv(int sockfd, void *buf, int len, int flags);
send() 會返回實際有送出的 byte 數,可能會少與所要傳送的數目。
recv()若返回0,則說明遠端那邊已經關閉了你的鏈接
close(sockfd);
關閉socket。
#include <netdb.h> #include <netinet/in.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <sys/types.h> #define MAX 80 #define PORT 8080 #define SA struct sockaddr // Function designed for chat between client and server. void func(int sockfd) { char buff[MAX]; int n; // infinite loop for chat for (;;) { bzero(buff, MAX); // read the message from client and copy it in buffer read(sockfd, buff, sizeof(buff)); // print buffer which contains the client contents printf("From client: %s\t To client : ", buff); bzero(buff, MAX); n = 0; // copy server message in the buffer while ((buff[n++] = getchar()) != '\n') ; // and send that buffer to client write(sockfd, buff, sizeof(buff)); // if msg contains "Exit" then server exit and chat ended. if (strncmp("exit", buff, 4) == 0) { printf("Server Exit...\n"); break; } } } // Driver function int main() { int sockfd, connfd, len; struct sockaddr_in servaddr, cli; // socket create and verification sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd == -1) { printf("socket creation failed...\n"); exit(0); } else printf("Socket successfully created..\n"); bzero(&servaddr, sizeof(servaddr)); // assign IP, PORT servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(PORT); // Binding newly created socket to given IP and verification if ((bind(sockfd, (SA*)&servaddr, sizeof(servaddr))) != 0) { printf("socket bind failed...\n"); exit(0); } else printf("Socket successfully binded..\n"); // Now server is ready to listen and verification if ((listen(sockfd, 5)) != 0) { printf("Listen failed...\n"); exit(0); } else printf("Server listening..\n"); len = sizeof(cli); // Accept the data packet from client and verification connfd = accept(sockfd, (SA*)&cli, &len); if (connfd < 0) { printf("server acccept failed...\n"); exit(0); } else printf("server acccept the client...\n"); // Function for chatting between client and server func(connfd); // After chatting close the socket close(sockfd); }
一個tcp client的示例代碼:
// Write CPP code here #include <netdb.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #define MAX 80 #define PORT 8080 #define SA struct sockaddr void func(int sockfd) { char buff[MAX]; int n; for (;;) { bzero(buff, sizeof(buff)); printf("Enter the string : "); n = 0; while ((buff[n++] = getchar()) != '\n') ; write(sockfd, buff, sizeof(buff)); bzero(buff, sizeof(buff)); read(sockfd, buff, sizeof(buff)); printf("From Server : %s", buff); if ((strncmp(buff, "exit", 4)) == 0) { printf("Client Exit...\n"); break; } } } int main() { int sockfd, connfd; struct sockaddr_in servaddr, cli; // socket create and varification sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd == -1) { printf("socket creation failed...\n"); exit(0); } else printf("Socket successfully created..\n"); bzero(&servaddr, sizeof(servaddr)); // assign IP, PORT servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); servaddr.sin_port = htons(PORT); // connect the client socket to server socket if (connect(sockfd, (SA*)&servaddr, sizeof(servaddr)) != 0) { printf("connection with the server failed...\n"); exit(0); } else printf("connected to the server..\n"); // function for chat func(sockfd); // close the socket close(sockfd); }
爲了讓client端和server中的內存數據庫,通訊若是server端和client創建鏈接以後則進入一個大循環,大循環的退出條件是client端發去「EXIT」,client端隨即斷開鏈接。
全部代碼都在github裏:slarsar/ttree_mmdb_tcp_server_client