C++ 简单socket服务端实现代码

做个笔记,注释以基本在代码里,废话不多说  PS:欢迎批评、指正、交流

#include <iostream>
#include <winsock2.h>
using namespace std;

//因为是用codeblocks编写的,所以要
//右击项目-> "build options..."->"linker setting"->"other linker options" 里面添加 “-lws2_32”
//#pragma comment(lib, "ws2_32.lib") 在VC/VS环境下启用

int main()
{
    /**< 1! 加载套接字版本库 2.2 */
    WSADATA wsaData;
    if(0 != WSAStartup(MAKEWORD(2, 2), &wsaData))
    {
        cout<<"load socket version error"<<endl;
        return 0;
    }
    /**< 1! */
    /**< 2! 创建套接字*/
    /*
    SOCKET socket(
    int af,       //指定地址族      如AF_INET决定了要用ipv4地址(32位的)与端口号(16位的)的组合
    int type,     //指定socket类型  常用SOCK_STREAM(面向连接的流式socket)和 SOCK_DGRAM(面向无连接的数据报式socket)
    int protocol  //指定协议        当为 0 时,自动选择与第二个参数匹配的协议,在不熟悉的情况下,建议一般设为 0
    );
    */
    SOCKET sockListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(sockListen == INVALID_SOCKET)
    {
        cout<<"create socket error"<<endl;
        return 0;
    }
    /**< 2! */
    /**< 3! 绑定 IP 和 端口 */
    sockaddr_in svrAddr;
    svrAddr.sin_family = AF_INET;
    svrAddr.sin_port = htons(8888);
    svrAddr.sin_addr.S_un.S_addr = INADDR_ANY;
    /*
    int bind(
    SOCKET s,                        //描述一个未绑定的套接字的描述符。即不可重复绑定
    const struct sockaddr FAR* name, //从sockaddr结构中分配到套接字的地址
    int namelen                      //name参数中值的长度
    );
    */
    if(bind(sockListen, (sockaddr*)&svrAddr, sizeof(svrAddr)) == INVALID_SOCKET)
    {
        cout<<"bind error"<<endl;
        return 0;
    }
    /**< 3! */
    /**< 4! 开启监听*/
    /*
    int listen(
    SOCKET s,    //描述一个绑定的、没有连接的套接字的描述符。
    int backlog  //等待连接的队列的最大长度。
    );
    */
    if(listen(sockListen, 10) == INVALID_SOCKET)
    {
        cout<<"listen error"<<endl;
        return 0;
    }
    /**< 4! */
    /**< 5! 数据接收*/
    SOCKET sockMSG;  //通讯套接字
    sockaddr_in remoteAddr;  //远程连接地址
    int nLen = sizeof(remoteAddr);
    /*
    SOCKET accept(
    __in     SOCKET s,               //描述一个套接字在监听函数中被置于监听状态的描述符
    __out    struct sockaddr* addr,  //一个可选的指针,用来接收连接实体的地址
    __inout  int* addrlen            //一个可选的指向一个整数的指针,它包含了addr参数所指向的结构的长度
    );
    */
    sockMSG = accept(sockListen, (sockaddr*)&remoteAddr, &nLen);
    if(sockMSG == INVALID_SOCKET)
    {
        cout<<"accept error"<<endl;
        return 0;
    }
    // remoteAddr.sin_addr 可以获得连接的客户端的IP地址
    /**< 5! */
    /**< 6! 数据接收和发送*/
    char recvBuf[255];
    memset(recvBuf, 1, sizeof(recvBuf));  //初始化  每声明一个数组,都应该立即执行初始化操作
    while(true)
    {
        /*
        int recv(
        SOCKET s,      //连接套接字描述符
        char FAR* buf, //用于输入数据的缓冲区。
        int len,       //buf参数的长度。
        int flags      //标记指定调用的方式。 一般为 0
        );  返回接收到的字节数
        */
        recv(sockMSG, recvBuf, sizeof(recvBuf), 0);
        cout<<recvBuf<<endl;
        /*
        int send(
        SOCKET s,            //连接套接字描述符
        const char FAR* buf, //包含要传输的数据的缓冲区
        int len,             //在buf参数中数据的长度
        int flags            //指示指定调用的方式  一般为 0
        );  如果没有发生错误,函数将返回发送的字节总数
        */
        const char *sendBuf = "hello TCP client";
        send(sockMSG, sendBuf, strlen(sendBuf), 0);

    }
    /**< 6! */
    /**< 7! 释放资源*/
    closesocket(sockMSG);
    closesocket(sockListen);
    WSACleanup();
    /**< 7! */
    return 0;
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值