跨平台 linux及windows中实现的tcp服务端 客户端可采用telnet进行测试 C11多线程实现

#include<stdio.h>
//#pragma comment(lib, "Ws2_32.lib")
#include <stdlib.h>
#include<string.h>
#include<thread>
#ifdef WIN32
#include<windows.h>
#else 
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>

#define closesocket close
#endif

using namespace std;
//三次握手是在客户端连接,服务端在listen后  就已经完成,跟accpet没有关系
//使用ulimit -n 查看linux中最大可以创建的socket数量
class TcpThread
{

public:
    void main()
    {
        char buf[1024] = { 0 };
        for (;;)
        {
            int len = recv(client, buf, sizeof(buf) - 1, 0);
            buf[len] = '\0';
            printf("recv %s\n", buf);

            if (strstr(buf, "quit") != 0)
            {
                char sendStr[] = "quit success !\n";
                int sendLen = send(client, sendStr, strlen(sendStr) + 1, 0);
                break;
            }
            int sendLen = send(client, "ok\n", 4, 0);
        }
        delete this;  //自己清理自己,确保这个对象是new出来的
        closesocket(client);
    }
    
    int client = 0;
};


int  main(int argc,char*argv[])
{

//linux中不需要加载网络库
#ifdef WIN32
    WSADATA ws;
    WSAStartup(MAKEWORD(2,2),&ws);
#endif
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    printf("[%d]\n", sock);

    //bind
    unsigned short port = 8080;
    //port 命令行参数传入
    if (argc > 1)
        port = atoi(argv[1]);

    sockaddr_in addr;
    addr.sin_addr.s_addr = htonl(0); //任意IP地址发过来都接收
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);   
    
    if (::bind(sock, (const sockaddr*)&addr, sizeof(addr)) != 0)
    {
        printf("bind port %d failed\n", port);
        return -1;
    }
    printf("bind port %d success\n", port);

    listen(sock, 10);  //该套接字使用的最大队列长度,代表最多同事监听10个客户端的连接
    //int client   = accept(sock, 0, 0);  //不关注客户端的信息
    sockaddr_in caddr;
    
#ifdef  WIN32
    int addrLen = sizeof(caddr);
#else
    socklen_t addrLen = sizeof(caddr);
#endif //  

    for (;;)
    {
        int client = accept(sock, (sockaddr*)&caddr, &addrLen);
        printf("accept client %d\n", client);
        if (client <= 0)
        {
            break;
        }
    
        char*ip = inet_ntoa(caddr.sin_addr);
        unsigned  short cport = ntohs(caddr.sin_port);
        printf(" client ip %s  port %d\n", ip, cport);

        TcpThread *th = new TcpThread;
        th->client = client;
        thread sth(&TcpThread::main,th);
        sth.detach();
    }

    closesocket(sock);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值