首页 > 编程语言 > 详细

C++之socket编程

时间:2020-07-20 01:17:46      阅读:100      评论:0      收藏:0      [点我收藏+]

环境搭建

  1. 开发环境- Clion
    本地安装了vs2017,可以选择使用vs自带的C++编译器,如下图:
    技术分享图片

  2. 引入库文件
    socket依赖winsocket.h、winsocket.lib和winsocket.dll
    在CMakeLists中:

#添加头文件搜索路径
link_libraries(ws2_32 wsock32)

获取网络中计算机的IP地址和计算机名

流式套接字编程

??网络数据的传输是靠套接字实现的。套接字有三种类型:流式套接字(socket_stream)、数据包套接字(socket_dgram)和原始套接字(RAW)。

??流式套接字是面向连接的,提供双向、有序、无重复且记录无边界的数据流服务。适用于处理大数据量,开销大

服务器端编程步骤

  1. 初始化阶段调用函数WSAStartup
    ??初始化Windows Sockets DLL,只有初始化成功后,才能调用其他Windows API函数。
void WSAStartup(
    _In_ WORD wVersionRequested,  // 所使用的win socket版本
    _Out_ LPWSADATA lpWSAData //储存系统返回的winSocket信息
    );
  1. 建立socket
    ??初始化动态链接后,在服务端建立一个监听socket
socket(
    _In_ int af,  // 目前提供PF_INET(AF_INET)
    _In_ int type,  // socket type, e.g. socket_stream(TCP),socket_dgram(UDP)
    _In_ int protocol  // 通讯协议,默认值0
    );

所有的WSASocket函数都可以通过调用 WSAGetLastError()获取上次错误

  1. 绑定端口
bind(
    _In_ SOCKET s,
    _In_reads_bytes_(namelen) const struct sockaddr FAR * name,  // socket地址,IP
    _In_ int namelen  // name的长度
    );

服务器端程序:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ws2tcpip.h>

using namespace std;

#define BUF_SIZE 1024

void initialization();

int main()
{
    //定义长度变量
    int send_len = 0;
    int recv_len = 0;
    int len = 0;
    //定义发送缓冲区和接受缓冲区
    char send_buf[100];
    char recv_buf[100];
    //定义服务端套接字,接受请求套接字
    SOCKET s_server;
    SOCKET s_accept;
    //服务端地址客户端地址
    SOCKADDR_IN server_addr;
    SOCKADDR_IN accept_addr;
    initialization();
    //填充服务端信息
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(5010);
    //创建套接字
    s_server = socket(AF_INET, SOCK_STREAM, 0);
    if (bind(s_server, (SOCKADDR *) &server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR)
    {
        cout << "套接字绑定失败!" << endl;
        WSACleanup();
    } else
    {
        cout << "套接字绑定成功!" << endl;
    }
    //设置套接字为监听状态
    if (listen(s_server, SOMAXCONN) < 0)
    {
        cout << "设置监听状态失败!" << endl;
        WSACleanup();
    } else
    {
        cout << "设置监听状态成功!" << endl;
    }
    cout << "服务端正在监听连接,请稍候...." << endl;
    //接受连接请求
    len = sizeof(SOCKADDR);
    s_accept = accept(s_server, (SOCKADDR *) &accept_addr, &len);
    if (s_accept == SOCKET_ERROR)
    {
        cout << "连接失败!" << endl;
        WSACleanup();
        return 0;
    }
    cout << "连接建立,准备接受数据" << endl;
    //接收数据
    while (1)
    {
        recv_len = recv(s_accept, recv_buf, 100, 0);
        if (recv_len < 0)
        {
            cout << "接受失败!" << endl;
            break;
        } else
        {
            cout << "客户端信息:" << recv_buf << endl;
        }
        cout << "请输入回复信息:";
        cin >> send_buf;
        send_len = send(s_accept, send_buf, 100, 0);
        if (send_len < 0)
        {
            cout << "发送失败!" << endl;
            break;
        }
    }
    //关闭套接字
    closesocket(s_server);
    closesocket(s_accept);
    //释放DLL资源
    WSACleanup();
    return 0;
}

void initialization()
{
    //初始化套接字库
    WORD w_req = MAKEWORD(2, 2);//版本号
    WSADATA wsadata;
    int err;
    err = WSAStartup(w_req, &wsadata);
    if (err != 0)
    {
        cout << "初始化套接字库失败!" << endl;
    } else
    {
        cout << "初始化套接字库成功!" << endl;
    }
    //检测版本号
    if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2)
    {
        cout << "套接字库版本号不符!" << endl;
        WSACleanup();
    } else
    {
        cout << "套接字库版本正确!" << endl;
    }
    //填充服务端地址信息

}

C++之socket编程

原文:https://www.cnblogs.com/zhuxiang1633/p/13341727.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!