各位尊敬的前辈,我在此真诚请教一下问题:
我写了个局域网通信程序:类似飞鸽的功能(没那么强),我动态获取用户在线信息正常(通过创建一个广播套接字,绑定窗口事件),但在文件传递时出现了问题。
我在程序启动后立即开启服务器:
void CTransferInfor::StartServer()
{
m_psockServer = new CListenSocket(this);
if(!m_psockServer->Create(m_port))
{
delete m_psockServer;
m_psockServer = NULL;
MessageBox(GetError(GetLastError()), _T("错误"), MB_ICONHAND);
return ;
}
//监听客户端连接
if(!m_psockServer->Listen())
{
delete m_psockServer;
m_psockServer = NULL;
MessageBox(GetError(GetLastError()), _T("错误"), MB_ICONHAND);
return ;
}
}对方连接时时正常的,我发送的一些响应信息能正常收到(文件名,大小,以及各种响应信息)我在在收到对方发过来的传送文件请求信息后,创建线程来发送文件:
注:pMsg 时我封装的一个消息类
if(pMsg->m_nType == REQUEST)//收到
{
m_bIsWait = TRUE; //是否已经取消传递的标记
m_strFileName = pMsg->m_strFileName;
m_dwFileSize = pMsg->m_dwFileSize;

CFileDialog dlg(FALSE, NULL, NULL, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, "所有文件 (*.*)|*.*||", this);
dlg.m_ofn.lpstrTitle = _T("另存为");
strcpy(dlg.m_ofn.lpstrFile, m_strFileName.GetBuffer(m_strFileName.GetLength()));
if(dlg.DoModal() == IDOK)
{
if(m_bIsWait == FALSE)//若对方已经取消等待
{
MessageBox(_T("对方已经取消文件发送"), _T("警告"),MB_ICONEXCLAMATION);
return ;
}
m_strPath = dlg.GetPathName();//获取保存路径
//启动接收文件的线程
pThreadListen = ::AfxBeginThread(_ListenThread, this);
return ;
}
                ........................我的线程函数如下:
UINT _ListenThread(LPVOID lparam)
{
CTransferInfor* pDlg = (CTransferInfor*)lparam;
CSocket* sockSrvr;
sockSrvr = new CSocket;
        /*注释:程序就在此处崩溃,直接跳出,也不跳出括号中的错误提示!”
if(!sockSrvr->Create(pDlg->m_port + 1000))
{
delete sockSrvr;
sockSrvr = NULL;
::MessageBox((HWND)lparam, pDlg->GetError(GetLastError()), _T("错误"), MB_ICONHAND|MB_OK);
return -1;
}
if(!sockSrvr->Listen())
{
//pDlg->TransfersFailed();
delete sockSrvr;
sockSrvr = NULL;
::MessageBox((HWND)lparam, pDlg->GetError(GetLastError()), _T("错误"), MB_ICONHAND|MB_OK);
return -1;
}
pDlg->SendMessage(WM_ACCEPT_TRANSFERS);//启动定时器标记,防止延时,在该函数里向对方发送消息:同意接收
//接受连接
CSocket recSo;
if(!sockSrvr->Accept(recSo))
{
AfxMessageBox("Accept失败!");
//::MessageBox((HWND)lparam, pDlg->GetError(GetLastError()), _T("错误"), MB_ICONHAND|MB_OK);
return -1;
} sockSrvr->Close();
AfxMessageBox("文件传递启动!");
pDlg->ReceiveFile(recSo);//具体的接受函数
return 0;
}
.........................请教各位,谁能给我指点一下原因,我始终不得其解。谢谢了

解决方案 »

  1.   

    怎么没用这个函数AfxSocketInit()先初始化套接字啊!建议服务器使用套接字顺序:
    1. if(!AfxSocketInit()){
    mwnd->MessageBox(_T("套接字初始化问题!请重试!"),_T("内部错误"));
    return 1;
    }
    2. if(!serversocket.Socket()){
    mwnd->MessageBox(_T("套接字初始化问题!请重试!"),_T("内部错误"));
    return 1;
    }
    CString sstr;
    3. if(!serversocket.Bind(ntser->GetPort(),ntser->GetIp())){
    mwnd->MessageBox(_T("端口绑定错误!请重试!"),_T("内部错误"));
    return 1;
    }
    4. if(!serversocket.Listen(10)){
    mwnd->MessageBox(_T("系统监听设置出现问题!请重试"),_T("内部错误"));
    return 1;
    }
    下面是实现的代码测试过可以用但只是基本通信:
    服务端的:
     
     
    CWinThread *pthread=NULL;
    UINT StartNetWork(LPVOID argv){
    if(!AfxSocketInit()){
      AfxMessageBox(_T("套接字无法初始化!"));
      AfxGetApp()->m_pMainWnd->PostMessage(WM_QUIT);
    }
    CSocket server;
    //CSocket server;
    if(!server.Socket()){
      AfxMessageBox(_T("套接字进一步初始化出现问题"));
      AfxGetApp()->m_pMainWnd->PostMessage(WM_QUIT);
    }
    if(!server.Bind(1000)){
      AfxMessageBox(_T("套接字绑定端口出现问题"));
      AfxGetApp()->m_pMainWnd->PostMessage(WM_QUIT);
    }
    if(!server.Listen(20)){
      AfxMessageBox(_T("套接字监听设置出现问题"));
      AfxGetApp()->m_pMainWnd->PostMessage(WM_QUIT);
    }
    CSocket acsock;
    AfxMessageBox(_T("successfull!"));
    while(true){
      if(!server.Accept(acsock)){
       continue;
      }else{
       char recemsg[256]={0};
       acsock.Receive(recemsg,256);
       AfxMessageBox(recemsg);
       acsock.Send("I Get Message!\0",30);
       acsock.Close();
      }
     
    客户端的(嵌入到你的请求函数):
    AfxSocketInit();
    CSocket csocket;
    if(!csocket.Create()){
      MessageBox(_T("客户端初始化失败"));
      this->PostMessage(WM_QUIT);
    }
    if(!csocket.Connect("127.0.0.1",1000)){
      char szMsg[1024]={0};
      sprintf(szMsg, "create faild: %d", csocket.GetLastError());
      AfxMessageBox(szMsg);
      this->PostMessage(WM_QUIT);
    }else{
      char szRecValue[1024] = {0};
      CString strText="dddddddddddd\0";
      csocket.Send(strText, strText.GetLength());
      csocket.Receive((void *)szRecValue, 1024);
      AfxMessageBox(szRecValue);
    } 最后一点基于CSocket的文件传输最好把文件分割传输(好像TCP虽然是流传输但是一次send最好在5k一下)。
      

  2.   

    AfxSocketInit()已经在另外的类中用过了
      

  3.   

    我的模型是:每个程序启都会开启一个TCP套接字,用于监视用户传递文件的需求,有就启动线程来处理.现在我的问题就是在我的线程里直接导致程序中断,我一时找不出原因。时间比较紧,马上就要中期检查了,哎.........
      

  4.   

    有沒有debug過!CSocket有時卻是很噁心 最好別把CSocket當作類的成員變量,當成一般的局部變量一般不會出現問題,而且如果你是一個線程對應一個客戶端請求的話最好還是用winsock APi直接編寫 因為不知道具體情況 所以也只能說這些
      

  5.   

    我断点调试过:在接收线程的一下语句出错:
    UINT _ListenThread(LPVOID lparam) 

    CTransferInfor* pDlg = (CTransferInfor*)lparam; 
    CSocket* sockSrvr; 
    sockSrvr = new CSocket; 
    /*注释:程序就在此处崩溃,直接跳出,也不弹出括号中的错误提示!” 
    if(!sockSrvr->Create(pDlg->m_port + 1000)) 

    delete sockSrvr; 
    sockSrvr = NULL; 
    ::MessageBox((HWND)lparam, pDlg->GetError(GetLastError()), _T("错误"), MB_ICONHAND|MB_OK); 
    return -1; 

    .......................
      

  6.   

    我断点调试过:在接收线程的一下语句出错:
    UINT _ListenThread(LPVOID lparam) 

    CTransferInfor* pDlg = (CTransferInfor*)lparam; 
    CSocket* sockSrvr; 
    sockSrvr = new CSocket; 
    /*注释:程序就在此处崩溃,直接跳出,也不弹出括号中的错误提示!” 
    if(!sockSrvr->Create(pDlg->m_port + 1000)) 

    delete sockSrvr; 
    sockSrvr = NULL; 
    ::MessageBox((HWND)lparam, pDlg->GetError(GetLastError()), _T("错误"), MB_ICONHAND|MB_OK); 
    return -1; 

    .......................
      

  7.   

    我打算不用CSocket,用WinSock,但我想问题不在这,因为我几条代码,我实在看不出问题,感觉很怪,呵呵,也许前面的代码有问题,我就想请问一下,一般出现这种情况会是由什么情况导致?
      

  8.   

    不要局部變量試一試,以前用 new CSocket()也好像出現這樣的問題,你是說Create()這個函數出錯把
      

  9.   

    是不是Invalid_socket 那個可能原因就多了
      

  10.   

    是不是Invalid_socket 那個可能原因就多了
      

  11.   

    //启动接收文件的线程 
    pThreadListen = ::AfxBeginThread(_ListenThread, this); 这个this 能明确是谁吗
      

  12.   

    但我想其他信息干扰不了这里啊,端口我也可以确保没被占用,监听端口用的是8000,这里用的是9000,(不一定使这两个端口,根据用户的IP来决定,防止端口的重复占用,从而导致出错。)CSocket *sock;....这几条语句执行有什么环境要求没?AfxSocketInit()我已调用。
      

  13.   

    會不會是Invalid_socket 斷點有沒有放在Create函數那一句,直接推出不報錯的情況很少,我對這個也不曉得
      

  14.   

    啊,没看见上面的回复,是在new 这句啊
    能不能先改成 CSocket sockSrvr; 试一下?
      

  15.   

    我是封装了CSocket类,一个CListenSocket,一个CCLientSocket,当Accept,Receive事件发生后调用当前窗口中的函数来响应
      

  16.   

    当然了,后面要用sockSrvr.Close();
      

  17.   

    就是那个(CSocket sockSrvr)改过来的,呵呵
      

  18.   

    可能程序某個地方退出了父線程沒了 子線程也被kill了 
    pThreadListen = ::AfxBeginThread(_ListenThread, this); 后加::Sleep(500000);試一試
      

  19.   

    THIS都肯定是DLG了,应该不会是父线程问题吧
    不过楼上想法应该试试
      

  20.   

    对啊,我的监听套接字用的就是封装过的
    CListenSocket* m_psockServer;//用于监听
    CClientSocket* m_psockClient;//用于连接,
             他们通过CArchive 传输控制信息,
    在程序中,这些控制信息都对的,当满足条件时,创建线程传文件或接收文件,现接收文件那个线程有问题,我重新创建一个CSocket socketServer用于监听,(端口已重新绑定),发送线程重新创建一个CSocket套接字用于传送,我想会不会是我前面那个m_psockServer 影响到了新的套接字的创建,他们使用同一个IP,但不同端口?
      

  21.   

    應該不會 這兩個獨立的套接字 不大可能會影響,但是你就直接用Create()不要帶任何參數 讓系統自己給你分配端口好 這樣肯定不會有衝突
    你在cmd下用netstat看看端口情況
      

  22.   

    谢谢以上两位,那么晚了还帮我回答问题,今早我改了:没用CSocket,用的是SOCKET直接来,发现能传递成功,但心里还是一直有很大的疑问?我的CSocket咋就不对了,现我也没多大功夫去研究它,时间紧,等后面再说,真有点不求甚解的意思。真希望有人替我解答一下我的疑问。
      

  23.   

    别在线程内 new指针 
    通过lparam传递到线程中去
      

  24.   

    我开始也没在线程里new,直接用的CSocket socketSer,一样有问题