最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 正文

在C++ Builder中用socket api来写网络通讯程序(同时支持TCP和UDP协议)

来源:动视网 责编:小OO 时间:2025-10-01 18:28:54
文档

在C++ Builder中用socket api来写网络通讯程序(同时支持TCP和UDP协议)

char hostname[128];  hostent* hn;  gethostname(hostname,128);  hn = gethostbyname(hostname);  IP地址=inet_ntoa(*(struct in_addr *)hn->h_addr_list[0]) IP_ADAPTER_INFO ipAdaInfo;  ULONG ipSize=sizeof(ipAdaInfo);  if(GetAdaptersInfo(&ipAdaInfo,&ipSize)==
推荐度:
导读char hostname[128];  hostent* hn;  gethostname(hostname,128);  hn = gethostbyname(hostname);  IP地址=inet_ntoa(*(struct in_addr *)hn->h_addr_list[0]) IP_ADAPTER_INFO ipAdaInfo;  ULONG ipSize=sizeof(ipAdaInfo);  if(GetAdaptersInfo(&ipAdaInfo,&ipSize)==
char   hostname[128];   

  hostent*   hn;   

  gethostname(hostname,128);   

  hn   =   gethostbyname(hostname);   

  IP地址=inet_ntoa(*(struct   in_addr   *)hn->h_addr_list[0])  

IP_ADAPTER_INFO   ipAdaInfo;   

  ULONG   ipSize=sizeof(ipAdaInfo);   

  if(GetAdaptersInfo(&ipAdaInfo,&ipSize)==ERROR_SUCCESS){   

  AfxMessageBox(ipAdaInfo.IpAddressList.IpAddress.String);//本机IP地址   

  }   

  你完全不必自己取IP,客户端接受socket连接后可以根据   

  IP包直接得到IP地址,取法为   

  sockaddr_in   remoteServer;   

  accept(listenSock,&remoteServer,sizeof(remoteServer));   

  char*   cIP=inet_ntoa(remoteServer.sin_addr);//得到该数据包源IP 

ring   的方法更通用,可以查别的机器的IP.   

    

  如果你要写Internet程序,就不能这样去取   

  IP地址,这样取的是局域网IP,不是你在Internet   

  上的真IP,一定得从IP中取得IP地址,即上面的   

  第二个方法.  

 

Socket api Client:

#ifndef UDPClientH

#define UDPClientH

#include

#include

#include

#include

#include

#include "CCEdit.h"

#define WM_SOCK WM_USER+100

class TLANForm : public TForm

{

__published: // IDE-managed Components

   TEdit *Port;

   TLabel *Label1;

   TLabel *Label2;

   TComboBox *Prot;

   TButton *Button1;

   TLabel *Label3;

   TEdit *Addr;

   TCCEdit *TxtEdit;

   void __fastcall FormCreate(TObject *Sender);

   void __fastcall Button1Click(TObject *Sender);

   void __fastcall FormDestroy(TObject *Sender);

private: // User declarations

   void __fastcall OnRecv(TMessage &Message);

public:  // User declarations

   __fastcall TLANForm(TComponent* Owner);

   BEGIN_MESSAGE_MAP

      VCL_MESSAGE_HANDLER(WM_SOCK,TMessage,OnRecv);

   END_MESSAGE_MAP(TForm);

};

extern PACKAGE TLANForm *LANForm;

#endif

.cpp File

#include

#pragma hdrstop

#include "UDPClient.h"

#include "WinSock.h"

#pragma package(smart_init)

#pragma link "CCEdit"

#pragma resource "*.dfm"

TLANForm *LANForm;

enum PROTO {TCP=0,UDP=1};

SOCKET m_Socket=INVALID_SOCKET;

PROTO m_Protocol=TCP;

__fastcall TLANForm::TLANForm(TComponent* Owner)

   : TForm(Owner)

{

}

void __fastcall TLANForm::FormCreate(TObject *Sender)

{

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

}

void __fastcall TLANForm::OnRecv(TMessage &Message)

{

   char buf[4096];

   int nLen;

   struct sockaddr_in from;

   int nLength=sizeof(struct sockaddr_in);

   switch(WSAGETSELECTEVENT(Message.LParam))

   {

      case FD_READ:

         switch(m_Protocol)

         {

            case TCP:

               nLen=recv(m_Socket,buf,4096,0);

               if(nLen>0){

                  buf[nLen]='\\0';

                  TxtEdit->Text="Received Length:"+String(nLen)+"\\r\\n"+StrPas(buf);

               }

               break;

            case UDP:

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

               if(nLen>0){

                  buf[nLen]='\\0';

                  TxtEdit->Text="Received Length:"+String(nLen)+"\\r\\n"+StrPas(buf);

               }

               break;

         }

         break;

      case FD_CLOSE:

         closesocket(m_Socket);

         break;

   }

}

void __fastcall TLANForm::Button1Click(TObject *Sender)

{

   char szTmp[256],buf[4096];

   int nSize=0;

   UINT m_Port;

   AnsiString addr;

   addr=Addr->Text.Trim();

   if(addr.IsEmpty()){

      ::MessageBox(0,"Please enter the server IP!

      return;

   }

   unsigned long nAddr=inet_addr(addr.c_str());

   if(nAddr==INADDR_NONE){

      ::MessageBox(0,"Bad Internet IP!

      return;}

   try

   {

      m_Port=Port->Text.ToInt();

   }

   catch(Exception &e)

   {

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

      return;

   }

   switch(Prot->ItemIndex)

   {

      case 0:

         m_Protocol=TCP;

         break;

      case 1:

         m_Protocol=UDP;

         break;

   }

   if(TxtEdit->Text.IsEmpty()){

      ::MessageBox(0,"Please enter the text you want to send!

      return;}

   file://Initialize Winsocket

   WSAData wsaData;

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

   WORD version=MAKEWORD(2,0);

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

      sprintf(szTmp,"Failed to initial winsock enviroment!,error no:%d",::WSAGetLastError());

      return;}

   file://Obtain the active connection

   char ComputerName[255];

   gethostname(ComputerName,255);

   struct hostent* he=gethostbyname(ComputerName);

   if(!he){

      sprintf(szTmp,"Failed to get information to host!

      ::WSACleanup();

      return;

   }

   file://create new socket

   m_Socket=INVALID_SOCKET;

   switch(m_Protocol)

   {

      case TCP:

         m_Socket=socket(AF_INET,SOCK_STREAM,0);

         break;

      case UDP:

         m_Socket=socket(AF_INET,SOCK_DGRAM,0);

         break;

   }

   if(m_Socket==INVALID_SOCKET){

      sprintf(szTmp,"Failed to create a new socket!,error no:%d",::WSAGetLastError());

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

      ::WSACleanup();

      return;

   }

   file://bind socket

   struct sockaddr_in client;

   unsigned long nClient;

   memcpy(&nClient,he->h_addr_list[0],sizeof(int));

   if(nClient==INADDR_NONE){

      sprintf(szTmp,"Failed to obtain the local machine's IP!

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

      closesocket(m_Socket);

      ::WSACleanup();

      return;

   }

   client.sin_family=AF_INET;

   client.sin_port=0;

   client.sin_addr.S_un.S_addr=(int)nClient;

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

      sprintf(szTmp,"Failed to bind socket!

      closesocket(m_Socket);

      ::WSACleanup();

      return;}

   file://connect socket

   struct sockaddr_in To;

   To.sin_family=AF_INET;

   To.sin_port=htons(m_Port);

   To.sin_addr.S_un.S_addr=(int)nAddr;

   fd_set FDSET;

   FD_ZERO(&FDSET);

   FD_SET(m_Socket,&FDSET);

   if(m_Protocol==TCP){

      if(connect(m_Socket,(struct sockaddr*)&To,sizeof(struct sockaddr))){

         sprintf(szTmp,"Failed to connect the object!,error no:%d",::WSAGetLastError());

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

         closesocket(m_Socket);

         ::WSACleanup();

         return;

      }

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

      if(nError<=0){

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

      closesocket(m_Socket);

      ::WSACleanup();

      return;}

   }

   file://Send data

   int nLen=TxtEdit->Text.Length();

   if(nLen>4096){

      sprintf(szTmp,"The buffer is too size to send,it shoud not be more than 4096 bytes!");

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

      closesocket(m_Socket);

      ::WSACleanup();

      return;

   }

   strncpy(buf,TxtEdit->Text.c_str(),nLen);

   switch(m_Protocol)

   {

      case TCP:

         nSize=send(m_Socket,buf,nLen,0);

         file://ShowMessage(nSize);

         break;

      case UDP:

         nSize=sendto(m_Socket,buf,nLen,0,(struct sockaddr*)&To,sizeof(struct sockaddr));

         file://ShowMessage(nSize);

         break;

   }

   if(::WSAAsyncSelect(m_Socket,Handle,WM_SOCK,FD_READ|FD_CLOSE)){

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

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

      closesocket(m_Socket);

      ::WSACleanup();

      return;}

}

void __fastcall TLANForm::FormDestroy(TObject *Sender)

{

   closesocket(m_Socket);

   ::WSACleanup();

}

Socket api Server:

.h File

#ifndef UDPServerH

#define UDPServerH

#include

#include

#include

#include

#include

#include "WinSock.h"

/*#define WM_SOCKET WM_USER+1000

#define INITSOCKETSUCCESS 0

#define INITSOCKETFAILURE 1

#define CREATELISTENSOCKETSUCCESS 2

#define CREATELISTENSOCKETFAILURE 3

#define SETLISTENSOCKETSUCCESS 4

#define SETLISTENSOCKETFAILURE 5

#define BINDLISTENSOCKETSUCCESS 6

#define BINDLISTENSOCKETFAILURE 7

#define LISTENSOCKETSUCCESS 8

#define LISTENSOCKETFAILURE 9

#define ACCEPTSOCKETSUCCESS 10

#define ACCEPTSOCKETFAILURE 11

*/

class TPSTNForm : public TForm

{

__published: // IDE-managed Components

   TEdit *Port;

   TLabel *Label1;

   TMemo *Memo1;

   TButton *Button1;

   TButton *Button2;

   TLabel *Label2;

   TComboBox *Prot;

   void __fastcall Button1Click(TObject *Sender);

   void __fastcall Button2Click(TObject *Sender);

   void __fastcall FormCreate(TObject *Sender);

   void __fastcall FormDestroy(TObject *Sender);

private: // User declarations

public:  // User declarations

   __fastcall TPSTNForm(TComponent* Owner);

};

enum PROTO {TCP,UDP};

class TCommunication:public TThread    file://Communication Thread

{

private:

   SOCKET m_AcceptSocket;

   char szTmp[256];//ERROR MESSAGE

public:

   __fastcall TCommunication(SOCKET m_Socket,bool CreateSuspended);

   __fastcall ~TCommunication();

protected:

   virtual void __fastcall Execute();

};

class TListenThread:public TThread file://Listen Thread

{

private:

   WSAData wsaData;

   struct sockaddr_in server;

   fd_set FDS;

   UINT m_Port;

   PROTO m_Protocol;

   char szTmp[256];//Error Message

public:

   SOCKET m_Socket;

   void __fastcall DoError();

   void __fastcall InitSocket();

   void __fastcall CreateListenSocket();

   void __fastcall SetListenSocket();

   void __fastcall BindListenSocket();

   void __fastcall ListenSocket();

public:

   __fastcall TListenThread(PROTO m_ProtocolA,UINT m_PortA,bool CreateSuspended);

   virtual __fastcall ~TListenThread();

protected:

   virtual void __fastcall Execute();

};

extern PACKAGE TPSTNForm *PSTNForm;

#endif

.cpp File

#include

#pragma hdrstop

#include "UDPServer.h"

#pragma package(smart_init)

#pragma resource "*.dfm"

TPSTNForm *PSTNForm;

TListenThread *pThread=0;

file://******************************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';

      file://Display

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

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

      file://Deliver

      ::Sleep(100);

      send(m_AcceptSocket,buf,nSize,0);

   }

}

file://******************************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;

  }

  file://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; file://for UDP

   int nLen=sizeof(from),nSize=0;  file://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();

   }

}

file://************************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);

   file://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:前缀就表示它是注释部分,特此声明,以免误解。

把   pCThread->Terminate();

      pCThread->WaitFor();

注释.(因为是新手原因不明)

否则的话TCP客户端运行时抱10061错误

文档

在C++ Builder中用socket api来写网络通讯程序(同时支持TCP和UDP协议)

char hostname[128];  hostent* hn;  gethostname(hostname,128);  hn = gethostbyname(hostname);  IP地址=inet_ntoa(*(struct in_addr *)hn->h_addr_list[0]) IP_ADAPTER_INFO ipAdaInfo;  ULONG ipSize=sizeof(ipAdaInfo);  if(GetAdaptersInfo(&ipAdaInfo,&ipSize)==
推荐度:
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top