windows下的C++ socket服务器(2)

windows下的C++ socket服务器(2)

int make_server_socket(int port);//1
void handleAccept(int socket_fd);//2
int main(int ac, char *av[])
{
    int tcp_socket = make_server_socket(8888);
    if (tcp_socket == -1)
    {
        exit(0);
    }
    thread t;//3
    while (1)
    {
        int socket_fd = accept(tcp_socket, nullptr, nullptr);  //4  
        t = thread(handleAccept, socket_fd);//3
        t.detach();//3
    }
    
    system("pause");
}

1.int make_server_socket(int port) 用于创建服务端的socket的函数,将在后面进行讲解。

2.void handleAccept(int socket_fd) 用于处理连接到服务端的客户端的函数,将在后面进行讲解。

3.thread C++11中出现的用于多线程编程,需要#include <thread> ,以前涉及到多线程编程时,在windows中需要使用CreateThread,而在linux中需要用pthread_create函数

而当thread出现后,在代码层面上,windows和linux就统一了。

thread的构造函数,

template<class _Fn,class... _Args> 
explicit thread(_Fn&& _Fx, _Args&&... _Ax)

{

//     

}

简单来说第一个参数表示函数的名字,其余的参数表示第一个参数所对应函数的参数,模板中的…用到了C++11中的变长模板这一个概念。

比如 t=thread(handleAccept,socket_fd)// handleAccept 函数名字,该函数有一个int的参数,socket_fd对应该int 参数

 

在线程创建完成后,我用t.detach(),将线程与主线程分离开,这样线程在线程结束时,就会清空自动该线程所占用的栈空间。并且主线程也可以和支线程一起运行,不用等待支线程结束后才能继续执行。

而如果我们如果使用t.join();会导致主线程必须等待所有当前的支线程结束后才可以往下执行。这样就无法同时处理不同客户端的请求了

还有要注意的是thread默认的joinable值是true,这意味着线程是不会析构的,在重复对同一对象创建线程时是会异常终止的,我们需要使用detach()和join(),将joinable的值改为false

 

例如

void print()
{
    string a("hello");
    cout << a << endl;
}
int main(int ac, char *av[])
{
    thread t;
    t = thread(print);
    //t.detach();
    t = thread(print);
    //t.detach();
    
    system("pause");
}


而如果我们把注释去掉就可以正常运行了,同样将t.detach()改为t.join()也可以。

 

关于thread的更多资料

http://www.oschina.net/translate/cplusplus-11-threading-make-your-multitasking-life

http://www.cnblogs.com/haippy/p/3236136.html

 

 

4.accept();

accept()函数在windows下

SOCKET accept(SOCKET s,sockaddr* addr,int* addrlen );

accept函数的第一个参数为服务器的socket描述字,第二个参数为指向struct sockaddr *的指针,用于返回客户端的协议地址,第三个参数为该协议地址的长度。如果accpet成功,那么返回一个socket,代表与返回客户的TCP连接。

在本程序中

int socket_fd = accept(tcp_socket, nullptr, nullptr);

tcp_socket是我们创建的服务器的socket描述字,而协议地址和该协议地址的长度,我们这里不需要,就设置为nullptr(nullptr为C++11 新增的用于替代null)

 

在这里accept函数是阻塞的,在没有新连接请求来的情况下,accept一直在这里等,函数没有返回,程序也不会往下运行。。

 

大家可以发现accept在windows中返回的SOCKET类型,而我们用一个int型接受返回值。

大家可以在vs2013中发现


所以SOCKET和int是可以进行转换的。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Windows平台上使用C++编写Socket套接字程序需要包含一些头文件和链接相应的库文件。首先,需要包含以下头文件: #include <string> #include <cstdio> #include <cstdlib> #include <iostream> #include <WinSock2.h> #include <Windows.h> 然后,需要链接ws2_32.lib库文件,可以使用#pragma comment(lib, "ws2_32.lib")来实现。 在服务器端(server.cpp)中,需要进行套接字的绑定操作。可以使用sockaddr_in结构体来指定套接字的IP地址和端口号,并使用bind函数将套接字与IP地址绑定: sockaddr_in sockAddr; memset(&sockAddr, 0, sizeof(sockAddr)); sockAddr.sin_family = PF_INET; sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); sockAddr.sin_port = htons(1234); bind(servSock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR)); 在客户端端(client.cpp)中,需要向服务器发送请求。可以使用connect函数将套接字与服务器的IP地址和端口号连接起来: sockaddr_in sockAddr; memset(&sockAddr, 0, sizeof(sockAddr)); sockAddr.sin_family = PF_INET; sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); sockAddr.sin_port = htons(1234); connect(sock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR)); 接下来,在客户端(client.cpp)中,可以使用循环来接收服务器端传回的消息。使用recv函数接收数据,并将接收到的数据转换为string类型进行处理。如果接收到的数据是"exit",则表示对方关闭了Socket,程序需要退出。否则,可以输出接收到的数据。 while (true) { char szBuffer\[MAXBYTE\] = { 0 }; int can = recv(sock, szBuffer, MAXBYTE, NULL); string buffer = szBuffer; if (buffer == "exit") { printf("对方关闭了Socket。\n"); closesocket(sock); WSACleanup(); system("pause"); exit(0); } printf("从server接收到的数据: %s\n", buffer.size() > 2 ? buffer.substr(1, buffer.size() - 1).c_str() : ""); } 在服务器端(server.cpp)中,也可以使用循环来根据用户输入给客户端传消息。使用send函数将消息发送给客户端。如果用户输入的是"exit",则表示要退出程序。 while (true) { printf("输入要发送的数据(要退出输入exit):"); string str; getline(cin, str); if (str != "exit") send(clntSock, ("k" + str + "k").c_str(), str.size() + sizeof(char), NULL); else { send(clntSock, "exit", 4 + sizeof(char), NULL); break; } } printf("成功退出!\n"); closesocket(clntSock); closesocket(servSock); WSACleanup(); system("pause"); 以上是一个简单的C++ Windows Socket套接字程序的示例。通过使用WinSock2.h和ws2_32.lib库文件,可以实现Socket通信功能。 #### 引用[.reference_title] - *1* *2* *3* [C++ WindowsSocket通信](https://blog.csdn.net/m0_66248056/article/details/128450302)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值