通过TCP与简易内存数据库进行数据交互的实现
目的
运用TCP相关原理,实现一个简单的server端和client端的数据库交互程序,可以将client端输入的指令被server端解析,将返回信息又返送给client端。
之前的简单内存数据库的实现:T-Tree、T*-Tree的理解与简单内存数据库的实现
TCP/IP,socket等相关计算机网络原理
七层网络模型
七层网络模型
TCP/IP
TCP/IP是互联网协议簇的统称。
TCP-transmission control protocal-传输控制协议
IP-Internet Protocal-因特网协议
UDP 是User Datagram Protocol 是无连接类型的传输层协议,
socket是什么
socket是对TCP/IP协议的封装,socket翻译为套接字,socket是一个接口/插座。
TCPIP 是Socket的一种实现,Socket并不只有TCP/IP。
两种socket:stream sockets,datagram socket
socket其实不止两种。
stream socket:串流式socket。是有连接类型的,网页浏览器所使用的 HTTP 协议是用 stream sockets 取得网页。
datagram socket:讯息式socket。是无连接类型的,用于语音通信,视频传输较多。
TCP server
server端
socket()函数
#include <sys/types.h> #include <sys/socket.h> int socket(int domain, int type, int protocol);
domain
一个地址描述。目前仅支持AF_INET格式,也就是说ARPA Internet地址格式。
type
指定socket类型。新套接口的类型描述类型,如TCP(SOCK_STREAM)和UDP(SOCK_DGRAM)。常用的socket类型有,SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等等。
protocol
指定协议。套接口所用的协议。如不想指定,可用0。常用的协议有,IPPROTO_TCP、IPPROTO_UDP、IPPROTO_STCP、IPPROTO_TIPC等,它们分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。
bind()函数
#include <sys/types.h> #include <sys/socket.h> int bind(int sockfd, struct sockaddr *my_addr, int addrlen);
bind()将一本地地址与一socket捆绑.
sockfd
sockfd 是 socket() 传回的 socket file descriptor。
my_addr
my_addr是指向包含你的地址资料丶名称及 IP address 的 struct sockaddr 之指针。
addrlen
addrlen 是以 byte 为单位的地址长度。
connect
#include <sys/types.h> #include <sys/socket.h> int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
connect()从client端连接到server端
listen(),accept()
int listen(int sockfd, int backlog); ----------------------------------------------------------------- #include <sys/types.h> #include <sys/socket.h> int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
send(),recv()
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()
close(sockfd);
关闭socket。
一个tcp server 的示例代码:
#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); }
client端
一个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); }
通过TCP与简易内存数据库的数据交互
为了让client端和server中的内存数据库,通信如果server端和client建立连接之后则进入一个大循环,大循环的退出条件是client端发去“EXIT”,client端随即断开连接。
通过TCP和内存数据库通信的所以代码
所有代码都在github里:slarsar/ttree_mmdb_tcp_server_client