C++基于Socket的TCP网络编程IPv6

2 篇文章 0 订阅

TCP服务端IPv6

// StudyC++Sokcet.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include<winsock2.h>//winsock2.0的头文件,链接windows的动态库
#include<ws2tcpip.h>//sockaddr_in6的头文件
using namespace std;//命名空间

//指定动态库的lib文件
#pragma comment(lib,"ws2_32.lib")

//TCP服务端IPv6版本
int main()
{
    

    //初始化winsock2.2相关的动态库
    WSADATA wd;//获取Socket相关信息
    if (WSAStartup(MAKEWORD(2, 2), &wd) != 0)//0标识成功 MAKEWORD版本
    {
        cout << "WSAStartup error:" << WSAGetLastError() << endl;//WSAGetLastError()获取错误
    }
    //
    //TCP Server的代码结构
    //1.创建TCP socket 流式套接字
    SOCKET s = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
    if (s == INVALID_SOCKET)//创建失败,返回错误信息
    {
        cout << "socket error:" << WSAGetLastError() << endl;
        return 0;
    }

    //2.绑定socket到一个IP地址和端口
    sockaddr_in6 addr;
    memset(&addr, 0, sizeof(sockaddr_in6));
    addr.sin6_port = htons(8000);//网络字节序,端口号
    addr.sin6_family = AF_INET6;//地址族
    //addr.sin6_addr = in6addr_any;//in6addr_any表示绑定任意ip地址(IPv6)
    //cmd ipconfig 查询本机IPv6地址
    inet_pton(AF_INET6, "fe80::7848:74a5:180a:a15b%12",&addr.sin6_addr);//绑定指定地址
    
    int len = sizeof(sockaddr_in6);//指定大小
    if (bind(s, (sockaddr*)&addr, len) == SOCKET_ERROR)//(sockaddr*)强制转换
    {
        //有时socket端口被占用了,也没办法bind就会返回错误
        cout << "bind error:" << WSAGetLastError() << endl;
        return 0;
    }
    //3.监听
    //s套接字,5也可用一个宏,表示正在等待完成相应TCP三路握手过程的队列长度
    if (listen(s, 5) == SOCKET_ERROR)
    {
        cout << "listen error:" << WSAGetLastError() << endl;
        return 0;
    }

    //4.接受客户端请求,并且返回和客户端通讯的套接字
    sockaddr_in6 addrClient;
    memset(&addrClient, 0, sizeof(sockaddr_in6));

    int lenClient = sizeof(addrClient);
    SOCKET c = accept(s, (sockaddr*)&addrClient, &lenClient);//成功返回clinet端的套接字
    if (c == INVALID_SOCKET)
    {
        cout << "accept error" << WSAGetLastError() << endl;
        return 0;
    }

    //5.发送、接收消息
    int ret = 0;
    do
    {   //向客户端发送数据,不能用监听套接字,要用返回套接字
        ret = send(c, "I am Server!", strlen("I am Server!"), 0);//把flag置0

        //接收客户端的消息
        char buf[64] = { "\0" };//初始化以免乱码
        ret = recv(c, buf, 64, 0);//把flag置0
        //cout << "recv:" << inet_ntoa(addrClient.sin_addr) << " : " << buf << endl;//inet_ntoa转化为IP字符串
        char ipbuf[20] = { 0 };
        inet_ntop(AF_INET6, (LPVOID)&addrClient.sin6_addr, ipbuf, 100);
        cout << "recv:" << ipbuf << " : " << buf << endl;
    } while (ret != SOCKET_ERROR && ret != 0);//成功返回接收到的字节数,错误返回SOCKET_ERROR,
    //对方关闭连接返回0,否则认为对方一直发送,我方循环接收
    //清理winsock环境

    //6.关闭套接字
    closesocket(s);
    ///
    WSACleanup();
    return 0;
    ///
}

TCP客户端IPv6

// TCP_Clinet.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include<winsock2.h>//winsock2.0的头文件,链接windows的动态库
#include<ws2tcpip.h>//sockaddr_in6的头文件
using namespace std;//命名空间

//指定动态库的lib文件
#pragma comment(lib,"ws2_32.lib")

//TCP客户端IPv6
int main()
{
    

    //初始化winsock2.2相关的动态库
    WSADATA wd;//获取Socket相关信息
    if (WSAStartup(MAKEWORD(2, 2), &wd) != 0)//0标识成功 MAKEWORD版本
    {
        cout << "WSAStartup error:" << WSAGetLastError() << endl;//WSAGetLastError()获取错误
    }

    //
    //TCP Clinet的代码结构
    //1.创建TCP socket 流式套接字
    SOCKET s = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);//地址族,套接字类型,协议----成功返回一个socket
    if (s == INVALID_SOCKET)//创建失败,返回错误信息
    {
        cout << "socket error:" << WSAGetLastError() << endl;
        return 0;
    }

    //2.链接服务端
    sockaddr_in6 addr;//sockaddr变种
    memset(&addr,0,sizeof(sockaddr_in6));
    addr.sin6_port = htons(8000);//网络字节序,端口号
    //指定连接的服务器如果用any步子到用什么服务器
    inet_pton(AF_INET6, "fe80::7848:74a5:180a:a15b%12", &addr.sin6_addr);
    addr.sin6_family = AF_INET6;//地址族
    int len = sizeof(sockaddr_in6);//指定大小
    if (connect(s, (sockaddr*)&addr, len) == SOCKET_ERROR)
    {
        cout << "connect error:" << WSAGetLastError() << endl;
        return 0;
    }

    //3.接收发送消息
    int ret = 0;
    do
    {
        //接收客户端的消息
        char buf[64] = { "\0" };
        ret = recv(s, buf, 64, 0);//把flag置0
        char ipbuf[100] = { 0 };
        inet_ntop(AF_INET6, (LPVOID)&addr.sin6_addr, ipbuf, 100);
        cout << "recv" << ipbuf << ":  " << buf << endl;//inet_ntoa
        //发送
        ret = send(s, "i am Client!", strlen("i am Client!"), 0);
        Sleep(1000);
    } while (ret != SOCKET_ERROR && ret != 0);

    //4.关闭套接字
    closesocket(s);
    ///
    WSACleanup();
    return 0;
    ///

}

先运行TCP_Server.exe,在运行TCP_Clinet.exe 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值