Windows系统TCP通信

 

接收数据:

#include <Windows.h>
#include <string>
#include <stdint.h>
using namespace std;
//网络编程在Windows平台上有俩个主要版本:Winsock1和Winsock2
#include <WinSock.h>
#pragma comment(lib, "WSock32.Lib")
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")

//自定义函数用来接收数据
static int recv_n(int s, uint8_t* p, int size, int flag){
    int n = 0, left = size;
    do{
        n = recv(s,(char*)p+size-left,left,flag);
        if(n<=0){
            return -1;
        }
        left -= n;
    }while(left>0);
    return size;
}

void main(){   
 //定义网络模块的版本MAKEWORD(2,1),具体试试看那个能用
    WORD socketVersion = MAKEWORD(2,2);
    WSADATA wsaData;
    if(WSAStartup(socketVersion, &wsaData) == 0){
        qDebug()<<"网络模块加载成功,可以进行网络通信";
    }
    //定义TCP接收端的套接字
    int _fdRecv = socket(AF_INET,SOCK_STREAM,0);
    //本地IP端口信息
    string _localAddr;//IP
    uint16_t _localPort;//端口
    struct sockaddr_in local;
    local.sin_family = AF_INET;
    local.sin_port = htons(_localPort);
    local.sin_addr.s_addr = inet_addr(_localAddr.c_str());
    //设置接收发送的最大延时,
    int recvTimeout = 3000;
    int sendTimeout = 3000;
    setsockopt(_fdRecv,SOL_SOCKET,SO_RCVTIMEO,(const char*)&recvTimeout,sizeof(recvTimeout));
    setsockopt(_fdRecv,SOL_SOCKET,SO_SNDTIMEO,(const char*)&sendTimeout,sizeof(sendTimeout));
    //设置缓存区大小:SO_SNDBUF发送端,SO_RCVBUF接收端
    int recvBufSize = 8*1024*1024;
    setsockopt(_fdRecv,SOL_SOCKET,SO_RCVBUF,(const char*)&recvBufSize,sizeof(recvBufSize));
   //将本机的IP端口信息配置给套接字
    if(bind(_fdRecv,(struct sockaddr*)&local,sizeof(local)) < 0){
        printf("bind error\n");
    }
    //listen:查看本机网络套接字是不是正常
    if (listen(_fdRecv, SOMAXCONN) == SOCKET_ERROR){
        printf("listen函数出错,错误码:%d\n", WSAGetLastError());
        return 0;
    }
    SOCKET _fdClient;//用来接收对面设备请求的套接字
    sockaddr_in remoteAddr;
    int nAddrlen = sizeof(remoteAddr);
    char revData[1024];
    //bool类型变量_quit可以控制我们什么时候开始去接收数据,什么时候停止接收数据
    while(!_quit){
        //死循环检查TCP必须是连接状态才能进行接收数据
        //accept函数本质是获取_fdRecv套接字,使用方法是判断TCP是不是连接状态
        while (true) {
            _fdClient = accept(_fdRecv, (SOCKADDR *)&remoteAddr, &nAddrlen);
            setsockopt(_fdClient,SOL_SOCKET,SO_RCVBUF,(const char*)&recvBufSize,sizeof(recvBufSize));
            if (_fdClient == INVALID_SOCKET){
                printf("accept error !");
                continue;
            }
            break;
        }
        //到了这一步,可以确定TCP连接正常了,可以进行数据接收了
        unsigned char header[16];
        ret = recv_n(_fdClient,header, 16, 0);
        if (ret <0 ){
            printf("header recv err!\n");
            break;
        }
        unsigned char* pData = new unsigned char[size];
        ret = recv_n(_fdClient, pData , size, 0);
        if (ret <0 ){
            printf("Data recv err!\n");
            break;
        }
    }
}

发送数据:

#include <Windows.h>
#include <string>
#include <stdint.h>
using namespace std;
//网络编程在Windows平台上有俩个主要版本:Winsock1和Winsock2
#include <WinSock.h>
#pragma comment(lib, "WSock32.Lib")
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
//自定义函数,发送数据
static int send_n(int s, uint8_t* p, int size, int flag){
    int n = 0, left = size;
    do{
        n = send(s,(char*)p+size-left,left,flag);
        if(n<=0){
            return -1;
        }
        left -= n;
    }while(left>0);
    return size;
}
void main()
{
    //定义网络模块的版本MAKEWORD(2,1),具体试试看那个能用
    WORD socketVersion = MAKEWORD(2,2);
    WSADATA wsaData;
    if(WSAStartup(socketVersion, &wsaData) == 0){
        qDebug()<<"网络模块加载成功,可以进行网络通信";
    }
    //定义TCP接收端的套接字
    int _fdSend = socket(AF_INET,SOCK_STREAM,0);
    //设置接收发送的最大延时,
    int sendTimeout = 3000;
    setsockopt(_fdSend,SOL_SOCKET,SO_SNDTIMEO,(const char*)&sendTimeout,sizeof(sendTimeout));
    //设置缓存区大小:SO_SNDBUF发送端,SO_RCVBUF接收端
    int BufSize = 8*1024*1024;
    setsockopt(_fdSend,SOL_SOCKET,SO_SNDBUF,(const char*)&BufSize,sizeof(BufSize));
    //本地IP端口信息
    //string _localAddr;//IP
    //uint16_t _localPort;//端口
    //struct sockaddr_in local;
    //local.sin_family = AF_INET;
    //local.sin_port = htons(_localPort);
    //local.sin_addr.s_addr = inet_addr(_localAddr.c_str());
    //将本机的IP端口信息配置给套接字
    //if(bind(_fdSend,(struct sockaddr*)&local,sizeof(local)) < 0){
    //    printf("bind error\n");
    //}
    //找到服务器端套接字端点地址
    sockaddr_in serAddr;
    serAddr.sin_family = AF_INET;
    serAddr.sin_port = htons(8888);
    serAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//目标机IP
    //每次发送都需要来一次connect判断,即是请求连接,也是连接状态判断
    if (connect(_fdSend, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR){
        //连接失败
        cout<<"Connect Failed !"<<endl;
        closesocket(_fdSend);
    }
    //将数据发送出去
    ret = send_n(_fdSend, (uint8_t*)sendData, size, 0);
}

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值