TCP网络编程的基本流程

TCP网络编程的基本流程

对于服务端,通常为以下流程:

  1. 调用socket函数创建socket
  2. 调用bind函数将socket绑定到某个IP和端口上
  3. 调用listen开始监听
  4. 当有客户端请求连接上来时,调用accept函数接受连接,产生一个新的socket
  5. 基于新产生的socket调用sendrecv函数,开始与客户端进行数据交流
  6. 通信结束后,调用close函数关闭套接字

对于客户端,通常为以下流程:

  1. 调用socket函数创建客户端socket

  2. 调用connect函数尝试连接服务器

  3. 连接成功后调用sendrecv函数,开始与服务器进行通信

  4. 通信结束后,调用close函数关闭socket

111

服务端代码实现如下:

#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>
#pragma clang diagnostic push
#pragma ide diagnostic ignored "EndlessLoop"
using std::cout;
using std::endl;
int main(int argc,char * argv[])
{
    //1.create socket
    int listenfd = socket(AF_INET,SOCK_STREAM,0);
    if(listenfd == -1)
    {
        cout<<"create listenfd failed"<<endl;
        return -1;
    }
    //2.Initialize server address
    struct sockaddr_in bindaddr{};
    bindaddr.sin_family =AF_INET;
    bindaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    bindaddr.sin_port= htons(3000);
    if (bind(listenfd,(struct  sockaddr*) &bindaddr, sizeof(bindaddr)) == -1)
    {
        cout<<"bind listen socket failed!"<<endl;
        return -1;
    }
    //3.Start listening
    if(listen(listenfd,SOMAXCONN) == -1)
    {
        cout<<"listen error"<<endl;
        return -1;
    }
    while (true)
    {
        sockaddr_in clientaddr{};
        socklen_t  clientaddrlen = sizeof(clientaddr);
        //4.accept client connect
        int clientfd = accept(listenfd,(struct sockaddr*)&clientaddr,&clientaddrlen);
        if (clientfd != -1)
        {
            //5.Receive data from the client
            char recvBuf[32]={0};
            int ret = recv(clientfd,recvBuf,32,0);
            if (ret > 0)
            {
                cout<<"Receive data from the client:"<<recvBuf<<endl;
                ret = send(clientfd,recvBuf, strlen(recvBuf),0);
                if(ret != strlen(recvBuf))
                    cout<<"send failed"<<endl;
                else
                    cout<<"send successfully"<<endl;
            }
            else
            {
                cout<<"Receive data error"<<endl;
            }
            close(clientfd);
        }
    }
    //7.close listen
    close(listenfd);
    return 0;
}
#pragma clang diagnostic pop

客户端代码

#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>

#define SERVER_ADDRESS "127.0.0.1"
#define SERVER_PORT 3000
#define SEND_DATA "helloworld"

int main(int argc,char *argv[])
{
    //1.create socket
    int clientfd = socket(AF_INET,SOCK_STREAM,0);
    if(clientfd == -1)
    {
        std::cout<<"create socket failed"<<std::endl;
        return -1;
    }

    //2.connect server
    sockaddr_in serveraddr;
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr= inet_addr(SERVER_ADDRESS);
    serveraddr.sin_port= htons(SERVER_PORT);
    if (connect(clientfd,(struct sockaddr*) &serveraddr, sizeof(serveraddr)) == -1)
    {
        std::cout<<"connect socket error"<<std::endl;
        return -1;
    }
    //3. send data to server
    int ret= send(clientfd,SEND_DATA, strlen(SEND_DATA),0);
    if (ret != strlen(SEND_DATA))
    {
        std::cout<<"send data failed"<<std::endl;
        return -1;
    }
    std::cout<<"successfully"<<SEND_DATA<<std::endl;

    //4.recv data from server
    char recvBuf[32] ={0};
    ret = recv(clientfd,recvBuf,32,0);
    if(ret >0)
    {
        std::cout<<"sucessfully"<<std::endl;
    } else
    {
        std::cout<<"failed"<<recvBuf<<std::endl;
    }
    //5.close socket
    close(clientfd);
    return 0;
}

TCP网络编程的基本流程

Linux与C++11多线程编程(学习笔记)

Linux select函数用法和原理

socket的阻塞模式和非阻塞模式(send和recv函数在阻塞和非阻塞模式下的表现)

connect函数在阻塞和非阻塞模式下的行为

获取socket对应的接收缓冲区中的可读数据量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值