tcp连接中的recv,send(cpp)

该博客展示了如何使用C++实现一个简单的TCP/IP服务器,通过socket接口进行客户端连接、数据接收与发送。程序涉及到了bind、listen、accept、recv和send等关键函数的使用,并在接收到特定字符串'quit'时终止通信。通过telnet工具可以远程连接并测试服务器功能。
摘要由CSDN通过智能技术生成

// 需要留一位放’/0’ (根据rec_len 表示数据截止的位置)

// 返回已经收到的数据大小,指定的大小不一定是实际接受的大小,只是指定最大收多少数据,必须返回*

 int rec_len = recv(client_sock,buf,sizeof(buf)-1,0);
 cout<<rec_len<<endl;
 buf[rec_len]='\0';
 if(rec_len<=0)
 {
 break;
 }
 cout<<"recive_len:"<<rec_len<<endl;
 cout<<"recive:"<<buf<<endl;

循环接受数据

接受到什么 就再发回去什么

接受到quit后,退出接受循环

for(;;)
    {
        memset(buf,0,1024);
        int rec_len = recv(client_sock,buf,sizeof(buf)-1,0);
        cout<<rec_len<<endl;
        buf[rec_len]='\0';
        if(rec_len<=0)
        {
            break;
        }
        cout<<"recive_len:"<<rec_len<<endl;
        cout<<"recive:"<<buf<<endl;
        int sendlen=send(client_sock,buf,1024,0);
        if(sendlen<=0)
        {
            break;
        }
        if(strstr(buf,"quit")!=NULL)
        {
            break;
        }

    }

完整代码

// socket_test.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <arpa/inet.h>
#include <iostream>
// 宏会在编译之前就执行,比如Linux时就不会有以下的代码
#ifdef WIN32 // 当存在WIN32的宏时,会执行中间的
#include <windows.h>

#else
#include <string.h>
#include <sys/types.h>          /* linux 引用这两个*/
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <stdlib.h>
#endif

using namespace std;
int main(int argc,char* argv[])
{

    unsigned short port=8080;
    if (argc>1)
    {
        port=atoi(argv[1]);//atoi 字符串转化为数字
    }

#ifdef WIN32 // 在linux中不需要以下的初始化
    // windows 调用socket 库 ,需要1. 初始化动态库  2. 引用lib库
    WSADATA ws;
    WSAStartup(MAKEWORD(2, 2), &ws);//也加载动态库,引用加1
#endif
    int sock=socket(AF_INET,SOCK_STREAM,0);//确定用什么协议,用tcp ip 小于0代表失败
    if(sock<0)
    {
        cout<<"连接失败"<<endl;
        return -1;
    }


    sockaddr_in saddr; //存取ip地址,port
    saddr.sin_family=AF_INET; //tcp/ip协议
    saddr.sin_port=htons(port); // 统一转化为大端存储(网络默认)
    saddr.sin_addr.s_addr=htonl(0);//一个机器可能有多个ip,这里默认任意ip都可以接受
    
    // socket 和 端口ip等信息绑定
    if(bind(sock,(sockaddr*)&saddr,sizeof(saddr))!=0)
    {
        cout<<"绑定失败"<<endl;
        return -2;
    }

    cout<<"绑定成功"<<endl;

    //开始监听
    listen(sock,10);

    // int client_sock=accept(sock,0,0); //0代表不想知道对方的连接信息 
    // // 会返回一个新的socket,与这个用户单独进行通信的,每一个连接都会生成一个socket
    // cout<<"client sock"<<client_sock<<endl;

    // 获取 连接客户端的ip和端口号
    sockaddr_in caddr;
    socklen_t len=0;
    int client_sock=accept(sock,(sockaddr*)&caddr,&len);
    cout<<"client sock"<<client_sock<<endl;
    string ip=inet_ntoa(caddr.sin_addr);
    cout<<"client ip:"<<ip<<endl;
    unsigned short cport=ntohs(caddr.sin_port);//把网络上转换成本地的,linux其实不需要
    cout<<"client port:"<<cport<<endl;


    //需要传client_sock,
    char buf[1024]={0};

    for(;;)
    {
        memset(buf,0,1024);
        int rec_len = recv(client_sock,buf,sizeof(buf)-1,0);
        cout<<rec_len<<endl;
        buf[rec_len]='\0';
        if(rec_len<=0)
        {
            break;
        }
        cout<<"recive_len:"<<rec_len<<endl;
        cout<<"recive:"<<buf<<endl;
        int sendlen=send(client_sock,buf,1024,0);
        if(sendlen<=0)
        {
            break;
        }
        if(strstr(buf,"quit")!=NULL)
        {
            break;
        }

    }
    // 需要留一位放'/0' 
    // 返回已经收到的数据大小,指定的大小不一定是实际接受的大小,只是指定最大收多少数据,必须返回
    // 
    int rec_len = recv(client_sock,buf,sizeof(buf)-1,0);
    cout<<"recive_len:"<<rec_len<<endl;
    cout<<"recive:"<<buf<<endl;
    #ifdef WIN32
        closesocket(sock);
    #else
        close(sock);
    #endif
    cout << sock << endl;
    std::cout << "Hello World!\n";
    std::cout << "Hello World!\n";
    return 0;

}
运行并启动监听
g++ socket_test.cpp -o socket_test
./socket
远程连接

telnet ip port

就可以看效果了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值