1. 程式人生 > >std::thread+socket 命令視窗無阻塞通訊

std::thread+socket 命令視窗無阻塞通訊

vs2013實驗可行:

main函式:

// thre.cpp : 定義控制檯應用程式的入口點。
//


#include "stdafx.h"
#include <stdlib.h>  
#include "serverthread.h"
#include <WINSOCK2.H>
#include <vector>
#pragma comment(lib,"ws2_32.lib")




vector<serverThread*> serverThreads;
void addd(SOCKET server)
{
sockaddr_in clientsock;
int len = sizeof(sockaddr);
while (true)
{
unsigned long ul = 1;
ioctlsocket(server, FIONBIO, (unsigned long *)&ul);//設定成非阻塞模式。  
SOCKET client = accept(server, (sockaddr*)&clientsock, &len);
if (SOCKET_ERROR == client)
{
int b = WSAGetLastError();
if (b == WSAEWOULDBLOCK)
{
//printf("阻塞\n");
}
else if (b == WSAETIMEDOUT)
{
//printf("超時\n");
}
else if (b == WSAENETDOWN)
{
//printf("斷開連線\n");
}
}
else
{
 
ioctlsocket(client, FIONBIO, (unsigned long *)&ul);//設定成非阻塞模式。  
serverThread* ser = new serverThread(client);
serverThreads.push_back(ser);
}
 







}

}


int _tmain(int argc, _TCHAR* argv[])
{
//建立套接字
WORD myVersionRequest;
WSADATA wsaData;
myVersionRequest = MAKEWORD(1, 1);
int err;
err = WSAStartup(myVersionRequest, &wsaData);
if (!err){
printf("已開啟套接字\n");
}
else{
printf("ERROR:巢狀字未開啟!");
return 1;
}


SOCKET server = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in serversock;
serversock.sin_family = AF_INET;
serversock.sin_port = htons(3000);
serversock.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
::bind(server, (sockaddr*)&serversock, sizeof(sockaddr));
listen(server, 5);




std::thread t(addd, server);
t.join();






for each (serverThread* var in serverThreads)
{
free(var);
}


closesocket(server);
WSACleanup();
 
 

system("pause");
return 0;
}


serverthread類:用來建立無阻塞socket
#pragma once




#include <thread>
#include <mutex> 
#include <condition_variable>
 
using namespace std;






class serverThread
{
public:
static bool finish;
static unsigned int num;
int flag_;
int nn;
std::mutex g_mutex;
std::condition_variable g_cond;
std::condition_variable g_cond2;
std::thread sendt;
std::thread recvt;
void sendFun(unsigned int num);
void recvFun(unsigned int num);
serverThread(unsigned int nn) /*sendt(std::bind(&serverThread::sendFun,this,12)),*/ 
{
this->nn = nn;
finish = true;
flag_ = 0;
sendt = thread(std::bind(&serverThread::sendFun, this, nn));
recvt = thread(std::bind(&serverThread::recvFun, this, nn));
sendt.detach();
recvt.detach();
}
~serverThread();


private:


};




#include "stdafx.h"
#include "serverthread.h"
#include <WINSOCK2.H>
#pragma comment(lib,"ws2_32.lib")


unsigned int serverThread::num = 0;
bool serverThread::finish = true;
serverThread::~serverThread()
{
finish = false;
closesocket(nn);
}


void serverThread::sendFun(unsigned int num)
{
SOCKET client = nn;
while (finish)
{
std::unique_lock<std::mutex> lg(g_mutex);
while (0 == flag_) {
g_cond.wait(lg);
}
char buf[100] = { 0 };
strcpy_s(buf, 100, "server:server");


int a = send(client, buf, strlen(buf) + 1, 0);

if (SOCKET_ERROR == a)
{
int b = WSAGetLastError();
if (b == WSAEWOULDBLOCK)
{
//printf("阻塞\n");
}
else if (b == WSAETIMEDOUT)
{
//printf("超時\n");
}
else if (b == WSAENETDOWN)
{
//printf("斷開連線\n");
}
}
else
{
printf("%s\n", buf);
flag_ = 0;
g_cond2.notify_one();
}
}
}


void serverThread::recvFun(unsigned int num)
{
SOCKET client = nn;
while (finish)
{
std::unique_lock<std::mutex> lg(g_mutex);
while (100 == flag_) {
g_cond2.wait(lg);
}
char buf[100] = { 0 };
int a = recv(client, buf, 99, 0);
if (SOCKET_ERROR == a)
{
int b = WSAGetLastError();
if (b == WSAEWOULDBLOCK)
{
//printf("阻塞\n");
}
else if (b == WSAETIMEDOUT)
{
//printf("超時\n");
}
else if (b == WSAENETDOWN)
{
//printf("斷開連線\n");
}
}
else
{
printf("%s\n", buf);
flag_ = 100;
g_cond.notify_one();
}
}
}



以上是伺服器程式碼,accept建立一個執行緒,之後每接收到一個客戶端就建兩個執行緒,一個用來接收資料,一個用來發送資料,全部無阻塞

本人菜鳥,歡迎各種提bug。

相關推薦

std::thread+socket 命令視窗阻塞通訊

vs2013實驗可行: main函式: // thre.cpp : 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include <stdlib.h> #include "serverthread.h" #include

C++初學者筆記:std::thread,子執行緒阻塞主執行緒的問題

C++ 11 支援跨平臺執行緒啦,當然要嚐嚐鮮 之前用的各平臺執行緒實現方式都不一樣,換個平臺或者換個庫,使用方法就不一樣了 編輯了個小例子,本來以為很容易,誰知道也要撞撞牆。 #include <stdio.h> #include <stdlib.h&g

java socket通訊I/O阻塞>多執行緒實現非阻塞通訊

簡單的java socket通訊,多個客戶端同時連線,功能可在此基礎上進行擴充套件。效果如圖: server: package com.lb.LB_Socket; import java.io.BufferedReader; import ja

Socket之-非阻塞通訊

本篇文章觀點和例子來自 《Java網路程式設計精解》, 作者為孫衛琴, 出版社為電子工業出版社。       對於用ServerSocket 及 Socket 編寫的伺服器程式和客戶程式, 他們在執行過程中常常會阻塞. 例如, 當一個執行緒執行 ServerSocket 的accept() 方法時, 假

Java簡單實現Socket阻塞通訊

        用java實現socket C/S通訊很簡單,很多教科書上都有。但是這些通訊模型大都是阻塞式的,其弊端也很明顯:一方必須要接收的到對方的訊息後,才能編輯自己的訊息發出。同樣對方也要一直等待這條訊息收到後才能傳送新的訊息。用網路通訊的知識講,大概就是半雙工通訊

win10“在此處開啟命令視窗”解決方法

第一步:新建一個txt檔案,命名為OpenCmdHere.txt 第二步:在檔案中輸入如下程式碼,並儲存Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\Directory\shell\OpenCmdHere]

Cocos2dx 3.0 過渡篇(二十七)C++11多線程std::thread的簡單使用(下)

fonts fun avi 2dx read 來源 cpp break 輸出 本篇接上篇繼續講:上篇傳送門:http://blog.csdn.net/star530/article/details/24186783簡單的東西我都說的幾乎相同了,想挖點深的差點把自己給填進

C# 委托高級應用----線程——創建阻塞的異步調用(一)

convert cal 參數 狀況 之間 輸入參數 非阻塞 嘗試 turn 前言 本文大部分內容來自於mikeperetz的Asynchronous Method Invocation及本人的一些個人體會所得,希望對你有所幫助。原英文文獻可以在codeproject中搜索

Linux Socket - 內核非阻塞功能

由於 有變 增加 連接建立 ioc eval type ddr ont select 函數 int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval*time

c++ std::thread + lambda 實現計時器

wake aps pen hide view color col pre pro 1 bool wait_for_wake = false; 2 std::mutex process_mutex; 3 std::condition_variable_any pro

std::thread

ring list BE reset ipa serve lee 參數 static std::thread為C++11的線程類,使用方法和boost接口一樣,非常方便。C++11的std::thread解決了boost::thread中構成參數限制的問題。 #incl

關於std::thread以及std::condition_variable的一些細節備忘

tor enc action sim cep 關於 pro swap not   也算是看過不少多線程相關的資料了,但是一直對於其中的一些細節沒有太好的把握,比如std::thread線程真正開始運行的時機,比如join、detch等真正的作用。 跟著《Cplusplus

socket程式設計socketpair父子程序通訊

#include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <unistd.h> #include <sys/t

MySQL命令視窗中文亂碼或插入中文資料失敗

在Windwos上使用命令視窗操作MySQL資料庫時,如果命令視窗的字元編碼與資料庫不一致時,就會出現中文亂碼的情況 比如查詢會出現中文亂碼,或者插入資料會出現錯誤“ERROR 1366 (HY000): Incorrect string value: '\xD5\xC5\xC8\xFD' for co

C++多執行緒之std::thread

C++11,包含標頭檔案 thread.h,並使用名稱空間std。 thread類提供的方法 方法 描述 thread 建構函式,在這裡傳入執行緒執行函式,和函式引數

1.Tomcat啟動不成功,命令視窗閃退問題和2.Eclipse Jee Oxygen無法釋出.html問題

一、Tomcat啟動不成功,命令視窗閃退問題 1.問題描述 在apache-tomcat-7.0.52\bin目錄下,雙擊“startup.bat”檔案執行tomcat 時,將命令視窗將出現閃退問題。 2.原因 沒有配置或者沒有正確配置JAVA_HOME的環境變數及JAVA_H

如何在DOS命令視窗中進入D盤?

如何在DOS命令視窗中進入D盤? 首先我們在電腦開始選單搜尋“執行”,點選回車,開啟執行 在裡面輸入CMD(大小寫都可以,然後Enter進入我們DOS命令視窗進行實驗!) 下面就是我們的DOS命令視窗:、 在命令列工具中輸入d:這樣就進入了

Golang通道的阻塞讀寫的方法示例

無論是無緩衝通道,還是有緩衝通道,都存在阻塞的情況,但其實有些情況,我們並不想讀資料或者寫資料阻塞在那裡,有1個唯一的解決辦法,那就是使用select結構。 這篇文章會介紹,哪些情況會存在阻塞,以及如何使用select解決阻塞。 阻塞場景 阻塞場景共4個,有快取和無緩衝各2個。 無緩

BAT簡單入門-命令視窗常用命令

命令視窗常用命令 1、cd 命令 cd       //顯示當前目錄 cd ..       //退出到上一個目錄 cd /d D:      //進入上次D盤所在目錄 cd /d d:\&nbs

今天遇到一個開心事,在eclipse編寫的程式碼在命令視窗中編譯後無法執行,提示 “錯誤: 找不到或無法載入主類”

java中帶package和不帶package的編譯執行方式是不同的。 首先來了解一下package的概念:簡單定義為,package是一個為了方便管理組織java檔案的目錄結構,並防止不同java檔案之間發生命名衝突而存在的一個java特性。不同package中的類的名字可以相同,只是在使用時要帶上pac