我目前正在开展高级项目,项目已基本完成,但我需要在不支持C ++ 11的VisualStudio 2010中实现多线程。因此我使用它作为多线程的来源(由我的导师建议)http://msdn.microsoft.com/en-us/library/windows/desktop/ms682516(v=vs.85).aspx,我完全迷失了如何用SOCKET实现它。
我的问题是我如何使用已编码的多线程套接字。以下是我到目前为止的情况。
typedef struct SenderData {
SOCKET socConnection;
} SENDERDATA, *PSENDERDATA;
DWORD WINAPI SenderThreadFunction( LPVOID lpParam){
HANDLE hStdout;
PSENDERDATA pDataArray;
TCHAR msgBuf[BUF_SIZE];
size_t cchStringSize;
DWORD dwChars;
// Make sure there is a console to receive output results.
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
if( hStdout == INVALID_HANDLE_VALUE )
return 1;
// Cast the parameter to the correct data type.
// The pointer is known to be valid because
// it was checked for NULL before the thread was created.
pDataArray = (PSENDERDATA)lpParam;
return 0;
}
此函数具有在telnet中启动会话并从文件
发送消息的所有命令DWORD WINAPI Sender(LPVOID lpParam){
}
以下创建连接,我最初在main()中创建了连接但不确定现在放在哪里
WSADATA wsaData; // Creates wsaData object
WSAStartup(MAKEWORD(2, 2), &wsaData); //Initializes Winsock
//Creates the socket object named "soc(Connection"
SOCKET socConnection = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
SOCKADDR_IN Addr;
HOSTENT* Host = gethostbyname("smtp.com");
Addr.sin_addr.s_addr = inet_addr(inet_ntoa(*(in_addr*)Host->h_addr_list[0]));
Addr.sin_family = AF_INET;
Addr.sin_port = htons(25);
如果我没有使用线程
,这将在main()中调用if (connect(Connection, (SOCKADDR*)&Addr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
cout << "Connection Failed" << endl;
在main()中执行以下代码时,如何将以前的代码置于启动状态? 我是C ++的新手,我非常感谢任何帮助。提前谢谢。
hThreadArray[0] = CreateThread(
NULL, // default security attributes
0, // use default stack size
Sender, // thread function name
pDataArray[0], // argument to thread function
0, // use default creation flags
&dwThreadIdArray[0]); // returns the thread identifier
答案 0 :(得分:0)
要在线程中运行的代码需要位于要传递给Sender()
的{{1}}函数内。这就是你的所有套接字调用(CreateThread()
和WSAStartup()
除外,只应调用一次)。
这样的事情:
WSACleanup()
答案 1 :(得分:0)
还有一些帮助,你如何将线程封装到类中以获得真正面向对象和更可重用的代码:
#include <windows.h>
#include <stdio.h>
#include <assert.h>
class CThread
{
public:
void Start()
{
assert(!m_Handle);
DWORD thread_id;
m_Handle = ::CreateThread(NULL, 0, StaticThreadProc, this, 0, &thread_id);
// this should be a fatal error/exit instead of a simple assert...
assert(m_Handle);
}
void Join()
{
assert(m_Handle);
::WaitForSingleObject(m_Handle, INFINITE);
}
protected:
virtual void Execute() = 0;
CThread() : m_Handle(NULL) {}
~CThread()
{
if (m_Handle)
{
Join();
::CloseHandle(m_Handle);
m_Handle = NULL;
}
}
private:
static DWORD WINAPI StaticThreadProc(LPVOID param)
{
CThread* thread = reinterpret_cast<CThread*>(param);
thread->Execute();
return 0;
}
private:
HANDLE m_Handle;
};
class CMyThread : public CThread
{
public:
CMyThread()
{
m_Sock = NULL;
m_Whatever = 0;
m_OtherParam = 0;
m_Result = 0;
}
// Use this to initialize the parameters for your thread before starting it...
// You could initialize from your constructor too if you wouldn't store your
// threads in an array by value...
void Init(SOCKET sock, int whatever_parameter_you_need, int other_param)
{
m_Sock = sock;
m_Whatever = whatever_parameter_you_need;
m_OtherParam = other_param;
}
int GetResult() const
{
return m_Result;
}
protected:
virtual void Execute() override
{
// Use m_Sock, m_Whatever, m_OtherParam ....
// Fill out m_Result before returning from the Execute() method of the thread.
// You can also create the socket inside the thread if you want,
// noone forces you to pass it here as an init parameter.
m_Result = 5;
}
private:
SOCKET m_Sock;
int m_Whatever;
int m_OtherParam;
int m_Result;
};
int main()
{
// TODO: network init (WSAStartup)
const int NUM_THREADS = 3;
CMyThread threads[NUM_THREADS];
// 1. Initializing threads with incoming parameters to work with
for (int i=0; i<NUM_THREADS; ++i)
{
//threads[i].Init(...)
}
// 2. Starting threads
for (int i=0; i<NUM_THREADS; ++i)
threads[i].Start();
// 3. Waiting for threads to finish...
for (int i=0; i<NUM_THREADS; ++i)
threads[i].Join();
// 4. Processing results if needed
int result0 = threads[0].GetResult();
printf("%d\n", result0);
// TODO: Network Cleanup (WSACleanup)
return 0;
}