Socket programming __tcp

Socket programming __tcp

tcp: Transmission Control Protocol: connection-oriented, reliable transmission, a byte stream oriented; scenario data security is greater than the real-time scene - file transfer. (Upper layers is not limited transmission data size)

udp network communication program flow:
Here Insert Picture Description
socket Interface description:
1. Create a socket

int socket(int domain, int type, int protocol)

domain: ---- different network address field address structure AF-INET (IPv4 address field)
type: Socket type - stream sockets / datagram sockets
stream sockets: an orderly reliable, bi-directional, connection-based streaming SOCK_STREAM byte
datagram socket: connectionless unreliable, there is the maximum length of transmission SOCK_DGRAM
protocol: protocol used at different socket types 0 ---- default protocol: stream sockets tcp / datagram socket default UDP
IPPROTO_TCP go - TCP protocol IPPROTO_UDP - udp protocol
return value: returns the operating handle socket file descriptors -----

2. The address bindings

int bind(int sockfd, struct sockaddr* addr, socklen_t len);

sockfd: socket creation operation handle returned.
addr: the address information of the structure to bind
len: the length of the address information
Return Value: return 0 if successful; -1 failure.

3. the server starts listening

int listen(int sockfd, int backlog);

backlog: the decision the same time, the server can accept client connection requests, but can not decide how many clients the server can accept parameters.
There is a connection pending queue parameters can indicate how much the client can accept. If the queue is filled, subsequent requests will be discarded.

4. Get the operating handle to the new socket

int accept(int sockfd, struct sockaddr* addr, socklen_t *len);

sockfd: listening socket - you want to get a socket which pending queue in
addr: get a socket, this socket to the specified client communication, access to the client information by addr
len: Specifies the address information wanted to return the length of the actual address length
return value: returns successfully acquired new socket descriptor; else return 1;

The received data

ssize_t recv(int sockfd, char *buf, int len, int flag);

sockfd: socket operation handle
buf: first address buffer for storing the received data, remove the data into the buffer buf user mode from the kernel buffer to receive the socket.
len: length of the data the user wants to read, but not more than the length of the buffer buf.
In Flag: 0 - Default blocking operation - if the buffer has no data waiting MSG_DONTWAIT- nonblocking
Return Value: returns a successful read of the actual number of data bytes; disconnected returns 0; else return 1;

6. Data transmission

ssize_t send(int sockfd, char* data, int len, int flag);

sockfd: socket handle operation, the transmission data is to copy the data to the kernel socket transmit buffer
data: address of the first data to be transmitted to
the length of the data to be transmitted: int_len
In Flag: 0 to default option parameter showing the current operation blocking operation MSG_DONTWAIT - set to a non-blocking
if sending data, socket send buffer is full, the default block waiting 0; MSG_DONTWAIT will immediately return an error.
Return Value: returns the data byte length actually successfully transmitted; failed return -1; exception is triggered if the connection is disconnected, the process exits.

7. Close the socket

int close(int fd);

8. The client sends a connection request to the server

int connect(int sockfd, int sockaddr* addr, socklen_t len);

sockfd: client socket - if not yet binding address, the operating system will select the appropriate source address binding
addr: server address information
len; address information length.

9. Code
1.tcpsocket.hpp

#pragma once
#include <cstdio>
#include <string>
#include<unistd.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/socket.h>


#define BACKLOG 10
#define CHECK_RET(q) if((q)==false){return -1;}
class TcpSocket
{
public:
    TcpSocket():_sockfd(-1){

    }
    //创建套接字
    bool Socket() {
        _sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if(_sockfd < 0) {
            perror("socket error");
            return false;
        }
        return true;
    }
    void Addr(struct sockaddr_in *addr, const std::string &ip, const uint16_t port) {
        addr->sin_family = AF_INET;
        addr->sin_port = htons(port);
        inet_pton(AF_INET, ip.c_str(), &(addr->sin_addr.s_addr));
    }
    bool Bind(const std::string &ip, const uint16_t port) {
        struct sockaddr_in addr;
        Addr(&addr, ip, port);
        socklen_t len = sizeof(struct sockaddr_in);
        int ret = bind(_sockfd, (struct sockaddr*)&addr, len);
        if(ret < 0)
        {
            perror("bind error");
            return false;
        }
        return true;
    }
    bool Listen(int backlog = BACKLOG){
        int ret = listen(_sockfd, backlog);
        if(ret < 0){
            perror("listen error");
            return false;
        }
        return true;
    }
    bool Connect(const std::string &ip, const uint16_t port) {
        struct sockaddr_in addr;
        Addr(&addr, ip,  port);
        socklen_t len = sizeof(struct sockaddr_in);
        int ret = connect(_sockfd, (struct sockaddr*)&addr, len);
        if(ret < 0) {
            perror("connet error");
            return false;
        }
        return true;
    }
    bool Accept(TcpSocket *sock, std::string *ip = NULL, uint16_t *port = NULL){
        struct sockaddr_in addr;
        socklen_t len = sizeof(struct sockaddr_in);
        int clisockfd = accept(_sockfd, (struct sockaddr*)&addr, &len);
        if(clisockfd < 0) {
            perror("accept error");
            return false;
        }
        sock->_sockfd = clisockfd;
        if(ip != NULL) {
            *ip = inet_ntoa(addr.sin_addr);
        }
        if(port != NULL) {
            *port = ntohs(addr.sin_port);
        }
        return true;
    }
    bool Send(const std::string &data) {
        int ret = send(_sockfd, data.c_str(), data.size(), 0);
        if(ret < 0) {
            perror("send error");
            return false;
        }
        return true;
    }
    bool Recv(std::string *buf) {
        char tmp[4096] = {0};
        int ret = recv(_sockfd, tmp, 4096, 0);
        if(ret < 0) {
            perror("recv error");
            return false;
        }else if(ret == 0){
            printf("connection break\n");
            return false;
        }
        buf->assign(tmp, ret);
        return true;
    }
    bool Close() {
        close(_sockfd);
        _sockfd = -1;
    }

private:
    int _sockfd;
};

2.tcp_cli.cpp

#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include "tcpSocket.hpp"

int main(int argc, char *argv[])
{
    if(argc != 3) {
        printf("em:./tcp_cli 172.17.0.1 9010 ---服务绑定的地址\n");
        return -1;
    }
    std::string ip = argv[1];
    uint16_t port = atoi(argv[2]);
    TcpSocket cli_sock;

    CHECK_RET(cli_sock.Socket());
    CHECK_RET(cli_sock.Connect(ip, port));

    while(1) {
        printf("client say:");
        fflush(stdout);
        std::string buf;
        std::cin >> buf;

       CHECK_RET(cli_sock.Send(buf));
       buf.clear();
       CHECK_RET(cli_sock.Recv(&buf));
       printf("server say: %s\n", buf.c_str());
    }
    cli_sock.Close();

    return 0;
}

3.tcp_srv.cpp

#include<iostream>
#include<stdlib.h>
#include "tcpSocket.hpp"

int main(int argc, char *argv[])
{
    if(argc != 3) {
        printf("em: ./tcp_srv 172.17.0.1 9010\n");
        return -1;
    }
    std::string ip = argv[1];
    uint16_t port = atoi(argv[2]);

    TcpSocket lst_sock;
    CHECK_RET(lst_sock.Socket());
    CHECK_RET(lst_sock.Bind(ip, port));
    CHECK_RET(lst_sock.Listen());
    while(1) {
        TcpSocket cli_sock;
        std::string cli_ip;
        uint16_t cli_port;

        bool ret = lst_sock.Accept(&cli_sock, &cli_ip, &cli_port);
        if(ret == false) {
            continue;
        }
        std::string buf;
        if(cli_sock.Recv(&buf) == false) {
            cli_sock.Close();
            continue;
        }
        printf("client:[%s:%d] say:%s\n", &cli_ip[0], cli_port, &buf[0]);
        std::cout << "server say;";
        fflush(stdout);
        buf.clear();
        std::cin >> buf;
        if(cli_sock.Send(buf) == false){
            cli_sock.Close();
            continue;
        }

    }
    lst_sock.Close();
    return 0;
}
Published 29 original articles · won praise 12 · views 1107

Guess you like

Origin blog.csdn.net/childemao/article/details/104897135