设为首页 加入收藏

TOP

C++ Builder中用socket api来写网络通讯程序(2)
2014-04-07 00:37:23 来源: 作者: 【 】 浏览:244
Tags:Builder 中用 socket api 网络通讯 程序

  //******************************CLASS TCommunication For TCP****************************************************

  __fastcall TCommunication::TCommunication(SOCKET m_Socket,bool CreateSuspended):TThread(FALSE)

  {

  m_AcceptSocket=m_Socket;

  szTmp[0]='\0';

  FreeOnTerminate=true;

  }

  __fastcall TCommunication::~TCommunication()

  {

  // closesocket(m_AcceptSocket);

  }

  void __fastcall TCommunication::Execute()

  {

  char buf[4096];

  int nSize=0;

  nSize=recv(m_AcceptSocket,(char FAR*)buf,4096,0);

  if(nSize>0)

  {

  buf[nSize]='\0';

  //Display

  PSTNForm->Memo1->Lines->Add("Received Length:"+String(nSize));

  PSTNForm->Memo1->Lines->Add("Received:"+StrPas(buf));

  //Deliver

  ::Sleep(100);

  send(m_AcceptSocket,buf,nSize,0);

  }

  }

  //******************************CLASS TListenThread*****************************************************

  __fastcall TListenThread::TListenThread(PROTO m_ProtocolA,UINT m_PortA,bool CreateSuspended):TThread(FALSE)

  {

  m_Socket=INVALID_SOCKET;

  m_Port=m_PortA;

  m_Protocol=m_ProtocolA;

  szTmp[0]='\0';

  ::ZeroMemory(&wsaData,sizeof(WSAData));

  ::ZeroMemory(&server,sizeof(struct sockaddr_in));

  FreeOnTerminate=TRUE;//Automatically delete while terminating.

  }

  __fastcall TListenThread::~TListenThread()

  {

  closesocket(m_Socket);

  ::WSACleanup();

  m_Socket=INVALID_SOCKET;

  m_Port=0;

  m_Protocol=TCP;

  szTmp[0]='\0';

  ::ZeroMemory(&wsaData,sizeof(WSAData));

  ::ZeroMemory(&server,sizeof(struct sockaddr_in));

  }

  void __fastcall TListenThread::DoError()

  {

  if(m_Socket!=INVALID_SOCKET) closesocket(m_Socket);

  WSACleanup();

  return;

  }

  void __fastcall TListenThread::InitSocket()

  {

  WORD version=MAKEWORD(2,0);

  if(::WSAStartup(version,&wsaData)){

  sprintf(szTmp,"Failed to intiailize socket,error no:%d",::WSAGetLastError());

  ::MessageBox(0,szTmp,"Error",MB_OK+MB_ICONERROR);

  DoError();

  return;

  }

  }

 

  void __fastcall TListenThread::CreateListenSocket()

  {

  switch(m_Protocol)

  {

  case UDP:

  m_Socket=socket(AF_INET,SOCK_DGRAM,0);

  break;

  case TCP:

  m_Socket=socket(AF_INET,SOCK_STREAM,0);

  break;

  default:

  sprintf(szTmp,"Error protocol!");

  ::MessageBox(0,szTmp,"Error",MB_OK+MB_ICONERROR);

  DoError();

  break;

  }

  if(m_Socket==INVALID_SOCKET){

  sprintf(szTmp,"Failed to create socket!");

  ::MessageBox(0,szTmp,"Error",MB_OK+MB_ICONERROR);

  DoError();

  return;

  }

  }

  void __fastcall TListenThread::SetListenSocket()

  {

  server.sin_family=AF_INET;

  server.sin_port=htons(m_Port);

  server.sin_addr.S_un.S_addr=INADDR_ANY;

  int NewOpenType=SO_SYNCHRONOUS_NONALERT;

  if(setsockopt(INVALID_SOCKET,SOL_SOCKET,SO_OPENTYPE,(char*)&NewOpenType,4)){

  sprintf(szTmp,"Set socket option error,error no:%d",::WSAGetLastError());

  ::MessageBox(0,szTmp,"Error",MB_OK+MB_ICONERROR);

  DoError();

  return;

  }

  }

  void __fastcall TListenThread::BindListenSocket()

  {

  if(bind(m_Socket,(sockaddr*)&server,sizeof(struct sockaddr_in))){

  sprintf(szTmp,"Failed to bind socket,error no:%d",::WSAGetLastError());

  ::MessageBox(0,szTmp,"Error",MB_OK+MB_ICONERROR);

  DoError();

  return;

  }

  }

  void __fastcall TListenThread::ListenSocket()

  {

  if(listen(m_Socket,SOMAXCONN)){

  sprintf(szTmp,"listen error,error no:%d",::WSAGetLastError());

  ::MessageBox(0,szTmp,"Error",MB_OK+MB_ICONERROR);

  DoError();

  return;

  }

  //Determine whether there is any connection

  FD_ZERO(&FDS);

  FD_SET(m_Socket,&FDS);

  }

  void __fastcall TListenThread::Execute()

  {

  char buf[4096];

  struct sockaddr_in from; //for UDP

  int nLen=sizeof(from),nSize=0;  //for UDP

  InitSocket();

  CreateListenSocket();

  SetListenSocket();

  BindListenSocket();

  if(m_Protocol==UDP){

  while(!Terminated){

  int nSize=recvfrom(m_Socket,buf,4096,0,(struct sockaddr*)&from,&nLen);

  if(nSize>0){

  buf[nSize]='\0';

  PSTNForm->Memo1->Lines->Add("Received Length:"+String(nSize));

  PSTNForm->Memo1->Lines->Add("Received:"+StrPas(buf));

  ::Sleep(100);

  sendto(m_Socket,buf,nSize,0,(struct sockaddr*)&from,sizeof(struct sockaddr_in));

  }

  else return;

  }

  }

 

  ListenSocket();

  struct sockaddr_in client;

  int nLength=sizeof(struct sockaddr_in);

  while(!Terminated){

  int nError=select(1,&FDS,0,0,0);

  if(nError<=0) Terminate();

  SOCKET m_AcceptSocket=accept(m_Socket,(struct sockaddr*)&client,&nLength);

  if(m_AcceptSocket==INVALID_SOCKET){

  sprintf(szTmp,"Failed to execute accept,error no:%d",::WSAGetLastError());

  ::MessageBox(0,szTmp,"Error",MB_OK+MB_ICONERROR);

  DoError();

  Terminate();

  return;

  }

  TCommunication *pCThread=new TCommunication(m_AcceptSocket,FALSE);

  pCThread->Terminate();

  pCThread->WaitFor();

  }

  }

  //************************PSTNForm*********************************************//

  __fastcall TPSTNForm::TPSTNForm(TComponent* Owner)

  : TForm(Owner)

  {

  }

  void __fastcall TPSTNForm::Button1Click(TObject *Sender)

  {

  Close();

  }

  void __fastcall TPSTNForm::Button2Click(TObject *Sender)

  {

  if(pThread){

  pThread->Suspend();

  pThread->Terminate();

  delete pThread;

  pThread=0;

  }

  UINT m_Port;

  try

  {

  m_Port=Port->Text.ToInt();

  }

  catch(Exception &e)

  {

  ::MessageBox(0,e.Message.c_str(),"Error",MB_OK+MB_ICONERROR);

  return;

  }

  PROTO m_Protocol;

  switch(Prot->ItemIndex)

  {

  case 0:

  m_Protocol=TCP;

  break;

  case 1:

  m_Protocol=UDP;

  break;

  default:

  break;

  }

  pThread=new TListenThread(m_Protocol,m_Port,FALSE);

  //pThread->Terminate();

  }

  void __fastcall TPSTNForm::FormCreate(TObject *Sender)

  {

  ::SendMessage(Prot->Handle,CB_SETCURSEL,0,1);

  }

  void __fastcall TPSTNForm::FormDestroy(TObject *Sender)

  {

  if(pThread){

  pThread->Suspend();

  pThread->Terminate();}

  }

  上面的代码,各位可根据自已的需要和针对自已的应用,在数据处理方面加以改进就可以了。

  再次声明,上述代码中出现的file:前缀这是csdn文档编辑器自动加的,各位凡是见到file:前缀就表示它是注释部分,特此声明,以免误解。

 

  void __fastcall TListenThread::CreateListenSocket()

  {

  switch(m_Protocol)

  {

  case UDP:

  m_Socket=socket(AF_INET,SOCK_DGRAM,0);

  break;

  case TCP:

  m_Socket=socket(AF_INET,SOCK_STREAM,0);

  break;

  default:

  sprintf(szTmp,"Error protocol!");

  ::MessageBox(0,szTmp,"Error",MB_OK+MB_ICONERROR);

  DoError();

  break;

  }

  if(m_Socket==INVALID_SOCKET){

  sprintf(szTmp,"Failed to create socket!");

  ::MessageBox(0,szTmp,"Error",MB_OK+MB_ICONERROR);

  DoError();

  return;

  }

  }

  void __fastcall TListenThread::SetListenSocket()

  {

  server.sin_family=AF_INET;

  server.sin_port=htons(m_Port);

  server.sin_addr.S_un.S_addr=INADDR_ANY;

  int NewOpenType=SO_SYNCHRONOUS_NONALERT;

  if(setsockopt(INVALID_SOCKET,SOL_SOCKET,SO_OPENTYPE,(char*)&NewOpenType,4)){

  sprintf(szTmp,"Set socket option error,error no:%d",::WSAGetLastError());

  ::MessageBox(0,szTmp,"Error",MB_OK+MB_ICONERROR);

  DoError();

  return;

  }

  }

  void __fastcall TListenThread::BindListenSocket()

  {

  if(bind(m_Socket,(sockaddr*)&server,sizeof(struct sockaddr_in))){

  sprintf(szTmp,"Failed to bind socket,error no:%d",::WSAGetLastError());

  ::MessageBox(0,szTmp,"Error",MB_OK+MB_ICONERROR);

  DoError();

  return;

  }

  }

  void __fastcall TListenThread::ListenSocket()

  {

  if(listen(m_Socket,SOMAXCONN)){

  sprintf(szTmp,"listen error,error no:%d",::WSAGetLastError());

  ::MessageBox(0,szTmp,"Error",MB_OK+MB_ICONERROR);

  DoError();

  return;

  }

  //Determine whether there is any connection

  FD_ZERO(&FDS);

  FD_SET(m_Socket,&FDS);

  }

  void __fastcall TListenThread::Execute()

  {

  char buf[4096];

  struct sockaddr_in from; //for UDP

  int nLen=sizeof(from),nSize=0;  //for UDP

  InitSocket();

  CreateListenSocket();

  SetListenSocket();

  BindListenSocket();

  if(m_Protocol==UDP){

  while(!Terminated){

  int nSize=recvfrom(m_Socket,buf,4096,0,(struct sockaddr*)&from,&nLen);

  if(nSize>0){

  buf[nSize]='\0';

  PSTNForm->Memo1->Lines->Add("Received Length:"+String(nSize));

  PSTNForm->Memo1->Lines->Add("Received:"+StrPas(buf));

  ::Sleep(100);

  sendto(m_Socket,buf,nSize,0,(struct sockaddr*)&from,sizeof(struct sockaddr_in));

  }

  else return;

  }

  }

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇64位CentOS 6.5安装GCC4.8.2+Qt5... 下一篇C++ builder消息的运用

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·在 Redis 中如何查看 (2025-12-26 03:19:03)
·Redis在实际应用中, (2025-12-26 03:19:01)
·Redis配置中`require (2025-12-26 03:18:58)
·Asus Armoury Crate (2025-12-26 02:52:33)
·WindowsFX (LinuxFX) (2025-12-26 02:52:30)