我想实现服务端用一个socket来listen,可以accept多个客户端的socket连接,并且为每个新连入的socket开一个线程,在线程内完成操作。写好的代码如下,运行起来后,服务端while循环里的accept在接受了一个客户端的连接后,好像无法阻塞然后等待新的socket请求了。
本来希望accept循环能阻塞,等新socket连入,然后才往下做。
另外,为连入的socket新建的线程是用来完成循环等待接收文件的,除非人为中止,否则是不会中止的。
我为每个socket新开一个线程的方法,有点问题,请问如何改进?请大家帮忙看看。服务端:
#include "stdafx.h"
#include "TransferSer.h"
#include "TransferSerDlg.h"
#include "winsock2.h"#pragma comment(lib,"Ws2_32.lib")#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endifCEvent g_eventStart;
CEvent g_eventKill;UINT ServerNetWork(LPVOID pParam)
{
::WaitForSingleObject(g_eventStart, INFINITE);
::ResetEvent(g_eventStart);        ..... //绑定
if (SOCKET_ERROR  == bind(listeningSocket, (SOCKADDR *) &serverAddrIN, sizeof(serverAddrIN)))
{
WSACleanup();
return 1;
}
//监听,队列为1
listen(listeningSocket, 5); while (true)
{
newConnection = accept(listeningSocket, (SOCKADDR *) &clientAddrIN, NULL);
AfxBeginThread(TransferFile, (LPVOID)newConnection); if (::WaitForSingleObject(g_eventKill, 0) == WAIT_OBJECT_0)
{
::ResetEvent(g_eventKill);
break;
}
}
WSACleanup();
return 0;
}UINT TransferFile(LPVOID pParam)
{
SOCKET LifConn;
LifConn = (SOCKET)pParam;
        ..... while (true)
{
if (::WaitForSingleObject(g_eventKill, 0) == WAIT_OBJECT_0)
{
break;
}                ....
} shutdown(LifConn, SD_RECEIVE);
closesocket(LifConn);
return 0;
}void CTransferSerDlg::OnButtonListen()
{
// TODO: Add your control notification handler code here
GetDlgItem(IDC_BUTTON_Listen)->EnableWindow(FALSE);
GetDlgItem(IDC_BUTTON_STOP)->EnableWindow(TRUE);
AfxBeginThread(ServerNetWork, GetSafeHwnd());
g_eventStart.SetEvent();
}void CTransferSerDlg::OnButtonStop()
{
// TODO: Add your control notification handler code here
g_eventKill.SetEvent();
GetDlgItem(IDC_BUTTON_Listen)->EnableWindow(TRUE);
GetDlgItem(IDC_BUTTON_STOP)->EnableWindow(FALSE);
}
客户端:
#include "stdafx.h"
#include "TransferClt.h"
#include "TransferCltDlg.h"
#include "winsock2.h"#pragma comment(lib,"Ws2_32.lib")#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CEvent g_eventStart;
CEvent g_eventKill;
CFile forSendFile;
CString pTargetFile = "DataForSend.txt";
CString m_strSendFilePathName = _T("");UINT ClientNetWork(LPVOID pParam)
{
::WaitForSingleObject(g_eventStart, INFINITE);
::ResetEvent(g_eventStart);        ..... //创建连接Socket
clientSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (clientSock == INVALID_SOCKET)
{
WSACleanup();
return 1;
}
//初始化协议族、地址、端口
remoteAddrIn.sin_family = AF_INET;
remoteAddrIn.sin_port = htons(port);
remoteAddrIn.sin_addr.s_addr =  inet_addr("127.0.0.1"); if (connect(clientSock, (SOCKADDR *) &remoteAddrIn, sizeof(remoteAddrIn))!= SOCKET_ERROR)
{
do
{
  ....
}while (pos < fileLenth); strcpy(sendInfo.type, strEnd);
send(clientSock, (char *) &sendInfo, sizeof(sendInfo), 0);
}
else
{
AfxMessageBox("连接失败");
return 1;
}
shutdown(clientSock, SD_SEND);
closesocket(clientSock);
return 0;
}void CTransferCltDlg::OnButtonConn() 
{
// TODO: Add your control notification handler code here
GetDlgItem(IDC_BUTTON_CONN)->EnableWindow(FALSE);
GetDlgItem(IDC_BUTTON_STOP)->EnableWindow(TRUE);
g_eventStart.SetEvent();
}void CTransferCltDlg::OnButtonStop() 
{
// TODO: Add your control notification handler code here
g_eventKill.SetEvent();
GetDlgItem(IDC_BUTTON_CONN)->EnableWindow(TRUE);
GetDlgItem(IDC_BUTTON_STOP)->EnableWindow(FALSE);
}