MFC(六)——Socket编程

OSI七层模型

  • OSI:开放系统互联(Open System Interconnection)
具体7层数据格式功能与连接方式典型设备
应用层 Application数据Data网络服务与使用者应用程序间的一个接口终端设备(PC、手机、平板等)
表示层 Presentation数据Data数据表示、数据安全、数据压缩终端设备(PC、手机、平板等)
会话层 Session数据Data会话层连接到传输层的映射;会话连接的流量控制;数据传输;会话连接恢复与释放;会话连接管理、差错控制终端设备(PC、手机、平板等)
传输层 Transport数据组织成数据段Segment用一个寻址机制来标识一个特定的应用程序(端口号)终端设备(PC、手机、平板等)
网络层 Network分割和重新组合数据包Packet基于网络层地址(IP地址)进行不同网络系统间的路径选择路由器
数据链路层 Data Link将比特信息封装成数据帧Frame在物理层上建立、撤销、标识逻辑链接和链路复用 以及差错校验等功能。通过使用接收系统的硬件地址或物理地址来寻址网桥、交换机
物理层Physical传输比特(bit)流建立、维护和取消物理连接光纤、同轴电缆、双绞线、网卡、中继器
  • TCP/IP与OSI参考模型的对应关系
    这里写图片描述

套接字(SOCKET)

  • 套接字的类型
    流式套接字(SOCK_STREAM):TCP
    数据报式套接字(SOCK_DGRAM):UDP

  • 基于TCP(面向连接)的socket编程

    服务器端程序

    • 1.创建套接字(socket)
    • 2.将套接字绑定到一个本地地址和端口上(bind)
    • 3.将套接字设为监听模式,准备接受客户请求(listen)
    • 4.等待客户请求到来;当请求到来后,接受连接请求,返回一个新的对应于此连接的套接字(accept)
    • 5.用返回的套接字和客户端进行通信(send/recv)
    • 6.返回,等待另一客户请求
    • 7.关闭套接字

    客户端程序

    • 1.创建套接字(socket)
    • 2.向服务器发出连接请求(connect)
    • 3.和服务器端进行通信(send/recv)
    • 4.关闭套接字
  • 基于UDP(面向无连接)的socket编程

    服务器端程序

    • 1.创建套接字(socket)
    • 2.将套接字绑定到一个本地地址和端口上(bind)
    • 3.等待接收数据(recvfrom)
    • 4.关闭套接字

    客户端程序

    • 1.创建套接字(socket)
    • 2.向服务器发送数据(sendto)
    • 3.关闭套接字
  • inet_addr()函数:可以将一个字符串作参数返回以点分十进制格式表示的IP地址

  • inet_ntoa()函数:反之
  • htonl()函数:转换u_long类型到网络字节序
  • htons()函数:转换u_short类型到网络字节序
  • bind函数中,TCP中经常用sockaddr_in代替sockaddr来方便填写信息
  struct sockaddr_in 
  {
        short   sin_family;//地址族,对于IP地址,常为AF_INET
        u_short sin_port;//端口号
        struct  in_addr sin_addr;//主机和IP地址
        char    sin_zero[8];//填充数,以使sockaddr_in结构和sockaddr结构的长度一样
};
  • TCP代码实例
//服务器端
#include <iostream>
#include <WinSock2.h> 
using namespace std;

#pragma comment(lib, "ws2_32.lib")

int main(int argc, char* argv[])
{
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;

    wVersionRequested = MAKEWORD(2, 2);

    err = WSAStartup(wVersionRequested, &wsaData);
    if (err != 0) 
    {
        cerr << "WSAStartup failed with error: " << err << endl;
        return 1;
    }

    if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) 
    {
        cerr << "Could not find a usable version of Winsock.dll" << endl;
        WSACleanup();
        return 1;
    }
    else
        cout << "The Winsock 2.2 dll was found okay" << endl;

    SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);
    SOCKADDR_IN addrSrv;
    addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(6000);

    bind(sockSrv, (sockaddr*)&addrSrv, sizeof(addrSrv));
    listen(sockSrv, 5);

    SOCKADDR_IN addrClient;
    int len = sizeof(SOCKADDR_IN);

    while (1) 
    {
        SOCKET sockCons = accept(sockSrv, (sockaddr*)&addrClient, &len);
        char sendBuf[100];
        sprintf_s(sendBuf, "Welcome %s to Flaming Chatting Room", inet_ntoa(addrClient.sin_addr));
        send(sockCons, sendBuf, strlen(sendBuf) + 1, 0);
        char recvBuf[100];
        recv(sockCons, recvBuf, 100, 0);
        cout << recvBuf << endl;
        closesocket(sockCons);
    }
    WSACleanup();
    return 0;
}
//客户端
#include <iostream>
#include <WinSock2.h> 
using namespace std;

#pragma comment(lib, "ws2_32.lib")

int main(int argc, char* argv[])
{
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;

    wVersionRequested = MAKEWORD(2, 2);

    err = WSAStartup(wVersionRequested, &wsaData);
    if (err != 0)
    {
        cerr << "WSAStartup failed with error: " << err << endl;
        return 1;
    }

    if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
    {
        cerr << "Could not find a usable version of Winsock.dll" << endl;
        WSACleanup();
        return 1;
    }
    else
        cout << "The Winsock 2.2 dll was found okay" << endl;

    SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);

    SOCKADDR_IN addrSrv;
    addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(6000);
    connect(sockClient, (sockaddr*)&addrSrv, sizeof(SOCKADDR));

    char recvBuf[100];
    recv(sockClient, recvBuf, 100, 0);
    cout << recvBuf << endl;
    send(sockClient, "this is zhangsan", strlen("this is zhangsan") + 1, 0);

    closesocket(sockClient);
    WSACleanup();

    return 0;
}
  • UDP代码实例
//服务器端
#include <iostream>
#include <WinSock2.h> 
using namespace std;

#pragma comment(lib, "ws2_32.lib")

int main(int argc, char* argv[])
{
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;

    wVersionRequested = MAKEWORD(2, 2);

    err = WSAStartup(wVersionRequested, &wsaData);
    if (err != 0)
    {
        cerr << "WSAStartup failed with error: " << err << endl;
        return 1;
    }

    if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
    {
        cerr << "Could not find a usable version of Winsock.dll" << endl;
        WSACleanup();
        return 1;
    }
    else
        cout << "The Winsock 2.2 dll was found okay" << endl;

    SOCKET sockSrv = socket(AF_INET, SOCK_DGRAM, 0);
    SOCKADDR_IN addrSrv;
    addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(6000);

    bind(sockSrv, (sockaddr*)&addrSrv, sizeof(sockaddr));

    SOCKADDR_IN addrClient;
    int len = sizeof(SOCKADDR);
    char recvBuf[100];

    recvfrom(sockSrv, recvBuf, 100, 0, (sockaddr*)&addrClient, &len);
    cout << recvBuf << endl;
    closesocket(sockSrv);
    WSACleanup();

    return 0;
}
//客户端
#include <iostream>
#include <WinSock2.h> 
using namespace std;

#pragma comment(lib, "ws2_32.lib")

int main(int argc, char* argv[])
{
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;

    wVersionRequested = MAKEWORD(2, 2);

    err = WSAStartup(wVersionRequested, &wsaData);
    if (err != 0)
    {
        cerr << "WSAStartup failed with error: " << err << endl;
        return 1;
    }

    if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
    {
        cerr << "Could not find a usable version of Winsock.dll" << endl;
        WSACleanup();
        return 1;
    }
    else
        cout << "The Winsock 2.2 dll was found okay" << endl;

    SOCKET sockClient = socket(AF_INET, SOCK_DGRAM, 0);
    SOCKADDR_IN addrSrv;
    addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(6000);

    sendto(sockClient, "Hello", strlen("Hello") + 1, 0, (sockaddr*)&addrSrv, sizeof(sockaddr));
    closesocket(sockClient);
    WSACleanup();

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值