c++非阻塞客户端/服务器TCP连接 socket编程代码示例

话不多说 直接上代码

服务器

#ifndef __TCP_SERVER__
#define __TCP_SERVER__
#include "tcpServer.h"
#include 
#include 
#include 
#include 
#include 


//网络库
#include 
//多线程
//#include 

//加载lib
#pragma comment(lib, "ws2_32.lib")

//端口定义
#define IPORT 36888
//实现bzero
#define bzero(a,b) memset(a, 0, b)
//监听队列最大数
#define BACK_LOG 1

using namespace std;

void main()
{
    // 返回值
    int ret;
    // WSA -> winsockapi
    WSADATA wsad;
    DWORD err;
    
    ret = WSAStartup(MAKEWORD(2, 2), &wsad);
    if (ret != 0)
    {
        perror("WSA startup failed");
        system("pause");
        exit(EXIT_FAILURE);
    }

    // 声明 socket
	SOCKET fd;
    // 声明 sockaddr_in 结构体
	sockaddr_in addr;


    // 接收计数
    static int recv_count = 0;
    
    // 创建服务器socket
	fd = socket(AF_INET, SOCK_STREAM, 0);
	if (fd == INVALID_SOCKET)
	{
		perror("socket init error");
        WSACleanup();
        system("pause");
		exit(EXIT_FAILURE);
	}

    // 结构体内存置0
    bzero(&addr, sizeof(addr));
    // tcp/udp
    addr.sin_family = AF_INET;
    // 接收任意地址
    addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    // 端口
    addr.sin_port = htons(IPORT);

    // 设置非阻塞 FIONBIO
    u_long is_non_block = 1;
    ret = ioctlsocket(fd, FIONBIO, &is_non_block);
    if (ret != 0)
    {
        perror("set non block failed");
        system("pause");
    }
    
    // 服务器socket绑定端口
    ret = ::bind(fd, (sockaddr*)&addr, IPORT);
    if (ret < 0)
    {
        perror("blind error");
        system("pause");
        exit(EXIT_FAILURE);
    }

    // 服务器开始监听 队列里最大可以支持10个客户端
    ret = listen(fd, BACK_LOG);
    if (ret < 0)
    {
        perror("listen error");
        system("pause");
        exit(EXIT_FAILURE);
    }
    cout << "server is listening..." << endl;

    std::vector sock_vec;

    while (1)
    {
        SOCKET cli_fd;

        int addrlen = sizeof(sockaddr);
        // 每次同时只能接收一个客户端的请求
        cli_fd = accept(fd, (sockaddr*)&addr, &addrlen);
        if (cli_fd != INVALID_SOCKET)
        {
            sock_vec.push_back(cli_fd);
        }
        else
        {
            err = WSAGetLastError();
        }

        //cout << "recieve count = " << recv_count << endl;
        Sleep(1000);
        char buf[1024];
        bzero(buf, sizeof(buf));
        for (auto it : sock_vec)
        {
            ret = recv(it, buf, sizeof(buf), 0);
            if (ret > 0)
            {
                recv_count++;
                cout << buf << endl;
                //std::system("pause");
            }
            else
            {
                err = WSAGetLastError();
                //socket断开
                if (ret < 0 && err != WSAEWOULDBLOCK)
                {
                    sock_vec.erase(it.getIterator());
                    perror("recieve failed");
                }
            }
        }
  
    }
    ret = WSACleanup();
    if (ret != 0)
    {
        err = WSAGetLastError();
        perror("WSA cleanup failed");
        system("pause");
        exit(EXIT_FAILURE);
    }
    std::system("pause");
}
#endif

客户端

#ifndef __TCP_CLIENT__
#define __TCP_CLIENT__

#include 
#include 
#include 
#include 
#include 

#include "tcpClient.h"
#pragma comment(lib, "Ws2_32.lib")

#define IPORT 36888
#define bzero(a,b) memset(a,0,b)
#define DST_ADDR "192.168.0.152"

using namespace std;

void main()
{
    int ret;
    DWORD err;
    WSADATA wsad;
    WSAStartup(MAKEWORD(2, 2), &wsad);
    if (ret != 0)
    {
        err = WSAGetLastError();
        cout << "WSAStartup failed, errcode is " << err << endl; 
    }
h:

    SOCKET s;
    sockaddr_in sa;
    s = socket(AF_INET, SOCK_STREAM, 0);
    if (s == INVALID_SOCKET)
    {
        err = WSAGetLastError();
        cout << "init socket failed, errcode is " << err << endl;
    }
    bzero(&sa, sizeof(sa));
    sa.sin_addr.S_un.S_addr = inet_addr(DST_ADDR);
    sa.sin_family = AF_INET;
    sa.sin_port = htons(IPORT);

    //cout << "please input client name" << endl;
    //char cli_name[100];
    //cin >> cli_name;
    //cout << "the client name is " << cli_name << endl;

    ret = connect(s, (SOCKADDR *)&sa, sizeof(sa));
    if (ret != 0)
    {
        err = WSAGetLastError();
        cout << "connect failed, errcode is " << err << endl;
    }
    char msg[1024];
    while (1)
    {
        cout << "please input the msg you want to send, input 0 to exit, 1 to reconnect server." << endl;
        //memcpy(msg, strcat(cli_name, msg), sizeof(cli_name));
        cin >> msg;
        if (strcmp(msg, "0\0") == 0)
        {
            closesocket(s);
            break;
        }
        if (strcmp(msg, "1\0") == 0)
        {
            closesocket(s);
            goto h;
            continue;
        }
        //string str = strcat(cli_name, msg);
        ret = send(s, msg, sizeof(msg), 0);
        if (ret < 0)
        {
            err = WSAGetLastError();
            cout << "send failed, errcode is " << err << endl;
        }
        bzero(msg, sizeof(msg));
    }
    WSACleanup();
    system("pause");
    //exit(0);
}

#endif

你可能感兴趣的:(c++)