vc++ 多线程编程 SOCKET通信

   vc++ 多线程编程 SOCKET通信

#include "StdAfx.h"
#include <stdio.h>
//服务器端程序
DWORD WINAPI AnswerThread(LPVOID lparam)
{
           SOCKET ClientSocket=(SOCKET)(LPVOID)lparam;
           char szText[]="您好!\r\n";
          int send_num=::send(ClientSocket,szText,strlen(szText),0);
         ::closesocket(ClientSocket);
      return 0;
        
}

int main()
{
           WSADATA wsaData;
           int iRet=WSAStartup(MAKEWORD(1,1),&wsaData); 
           SOCKET m_socket;
           m_socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
           if(m_socket==INVALID_SOCKET)
           {
                       WSACleanup();
                       return 0;
           }
           sockaddr_in service;
           service.sin_family=AF_INET;
           service.sin_addr.s_addr=inet_addr("172.16.3.250");
           service.sin_port=htons(2501);

           if(bind(m_socket,(SOCKADDR*)&service,sizeof(service))==SOCKET_ERROR)
           {
                       closesocket(m_socket);
                       return 0;
           }
           else
                       printf("bind OK.\n");
           if(listen(m_socket,20)==SOCKET_ERROR)
                       printf("Error listening on socket.\n");
           else
                       printf("listening ok.\n");
           SOCKET AcceptSocket;            
           printf("Waiting for a client to connect...\n");
           while(1)
           {
                       AcceptSocket=SOCKET_ERROR;
                       while(AcceptSocket==SOCKET_ERROR)
                       {
                                   AcceptSocket=accept(m_socket,NULL,NULL);
                       }                     
                       printf("Client Connected.\n");                        
                       DWORD dwThreadId;
                       HANDLE hThread;
                        
                       hThread=CreateThread(NULL,NULL,AnswerThread,
                                       (LPVOID)AcceptSocket,0,&dwThreadId);
                       closehandle(hThread);
                      //Sleep(4000);
                       closesocket(AcceptSocket);
          }
          closesocket(m_socket);           
           return 0;
}
 


该服务器端程序为什么如果有注释掉的Sleep(4000)客户端就接收返回正确的数据,注释掉后就接受到0个字符??
    提问者: wiggle_waggle - 实习生 一级 最佳答案你给客户端发送数据是用send么
如果没Sleep的话,你创建了一个新线程,创建新线程的同时,当前线程也在运行,socket都被你关掉了,还怎么send??
线程跟函数是不同的,函数是等调用结束后才执行下一个语句
int send_num=::send(ClientSocket,szText,strlen(szText),0); 应该要修改为:int send_num=::send(ClientSocket,szText,strlen(szText)+1,0);
不过,这与你的问题无关。
转自:http://zhidao.baidu.com/question/110558487.htmlfr=qrl&cid=866&index=3&fr2=query


在VC++ 的 MFC中 函数经过多线程编程后不能运行??
悬赏分:20 - 解决时间:2009-3-2 19:52
本来一个函数为
void function()
{
  CvCapture* capture = 0; 
  capture = cvCaptureFromCAM(0);
  if( !capture )
  {
   //fprintf(stderr,"Could not initialize capturing...\n");
   AfxMessageBox("Could not initialize capturing...");
  } 
  for(;;)
  {
   IplImage* frame = 0;  
   frame = cvQueryFrame( capture );
   if( !frame )
    break;  
   CDC *pDC = GetDlgItem(IDC_STATIC)->GetDC();
   CvvImage cimg;
   HDC hDC= pDC->GetSafeHdc();
   CRect rect;
   GetDlgItem(IDC_STATIC)->GetClientRect(&rect);  
   cimg.CopyOf(frame); //gFrame是那帧图像
   cimg.DrawToHDC(hDC,&rect);  
   ReleaseDC(pDC);
  }
 
cvReleaseCapture( &capture );
}
是没有问题的。多线程编程中由于要把函数定义成全局型的所以就变成:
DWORD WINAPI LoadVideo(LPVOID pParam)
{
  CVideoDlg dlg;
  CvCapture* capture = 0; 
  capture = cvCaptureFromCAM(0); 
  if( !capture )
  {
   //fprintf(stderr,"Could not initialize capturing...\n");
   AfxMessageBox("Could not initialize capturing...");
  } 
  for(;;)
  {
   IplImage* frame = 0;  
   frame = cvQueryFrame( capture );
   if( !frame )
    break;   
   CDC *pDC = dlg.GetDlgItem(IDC_STATIC)->GetDC();
   CvvImage cimg;
   HDC hDC= pDC->GetSafeHdc();
   CRect rect;
   dlg.GetDlgItem(IDC_STATIC)->GetClientRect(&rect);  
   cimg.CopyOf(frame); //gFrame是那帧图像
   cimg.DrawToHDC(hDC,&rect);  
   dlg.ReleaseDC(pDC);
  }
cvReleaseCapture( &capture );
return 1;
}
然后再用CreateThread函数调用。编译没问题。但是 运行后就弹出了程序出错对话框。如图所示。请问是什么原因呢?
      最佳答案把这个全局函数的功能全写回到你的成员函数里,然后你调用线程时将当前的this指针传进去,再在这个全局函数调用你的成员函数(通过传入的this指针调用,记得将参数强制转换回你原来的类型)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
网络编程之远程屏幕抓取程序,有源码!!直接可用!! #include "StdAfx.h" #include <stdio.h> DWORD WINAPI AnswerThread(LPVOID lparam) { SOCKET ClientSocket=(SOCKET)(LPVOID)lparam; int bytesRecv; char sendbuf[32]=""; char recvbuf[32]=""; while(1) { bytesRecv=SOCKET_ERROR; for(int i=0;i<(int)strlen(recvbuf);i++) { recvbuf[i]=´\0´; } while(bytesRecv==SOCKET_ERROR) { //Receiving Data bytesRecv=recv(ClientSocket,recvbuf,32,0); } //Write your processing code here send(ClientSocket,recvbuf,strlen(recvbuf),0); printf("%s\n",recvbuf); } return 0; } int main(int argc,char* argv[]) { //initialize Winsock WSADATA wsaData; int iRet=WSAStartup(MAKEWORD(2,2),&wsaData); if(iRet!=NO_ERROR) printf("Error at WSAStartup()\n"); //create a socket SOCKET m_socket; m_socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if(m_socket==INVALID_SOCKET) { printf("Error at socket():%ld\n",WSAGetLastError()); WSACleanup(); return 0; } //bind a socket sockaddr_in service; service.sin_family=AF_INET; service.sin_addr.s_addr=inet_addr("172.16.3.250"); service.sin_port=htons(2501); if(bind(m_socket,(SOCKADDR*)&service,sizeof(service))==SOCKET_ERROR) { printf("bind() failed.\n"); closesocket(m_socket); return 0; } else printf("bind OK.\n"); //listen on a socket if(listen(m_socket,20)==SOCKET_ERROR) printf("Error listening on socket.\n"); else printf("listening ok.\n"); //accept a connection SOCKET AcceptSocket; printf("Waiting for a client to connect...\n"); while(1) { AcceptSocket=SOCKET_ERROR; while(AcceptSocket==SOCKET_ERROR) { AcceptSocket=accept(m_socket,NULL,NULL); } printf("Client Connected.\n"); DWORD dwThreadId; HANDLE hThread; hThread=CreateThread(NULL,NULL, AnswerThread, (LPVOID)AcceptSocket,0,&dwThreadId); if(hThread==NULL) { printf("CreatThread AnswerThread() failed.\n"); } else { printf("CreateThread OK.\n"); } } return 0; }

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值