通过TCP与简易内存数据库进行数据交互的实现

目的

运用TCP相关原理,实现一个简单的server端和client端的数据库交互程序,可以将client端输入的指令被server端解析,将返回信息又返送给client端。

之前的简单内存数据库的实现:T-Tree、T*-Tree的理解与简单内存数据库的实现

TCP/IP,socket等相关计算机网络原理

七层网络模型

七层网络模型
通过TCP与简易内存数据库进行数据交互的实现

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

通过TCP与简易内存数据库进行数据交互的实现

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

参考

GeeksforGeeks
Beej's Guide to Network Programming 简体中文版

相关推荐