[C++] Windows下的socket編程(這是一個簡單的TCP/IP例子)

來源:互聯網
上載者:User

Socket的概念:

Socket,即通訊端,用於描述地址和連接埠,是一個通訊鏈的控制代碼。

應用程式通過Socket像網路發出請求或者回應。

什麼事客戶/伺服器模式:

在TCP/IP網路應用中,通訊的兩個進程相互作用的主要模式是客戶/伺服器模式,即用戶端向伺服器發出請求,伺服器接收請求後,提供相應的服務。客戶/伺服器模式的建立基於以下兩點:

1:建立網路的起因是網路中軟硬體資源、運算能力和資訊不均等,需要共用,從而造就擁有眾多資源的主機提供服務,資源較少的客戶請求服務這一非對等作用

2:網間進程通訊完全是非同步,相互連信的進程間既不存在父子關係,又不共用記憶體緩衝區

因此需要一種機製為希望通訊的進程間建立聯絡,為二者的資料交換提供同步,這就是基於客戶/服務端模式的TCP/IP

(這部分內容摘自socket編程原理)


需要做什麼:

用戶端:建立Socket,通過連接埠號碼和地址確定目標伺服器,使用Connect串連到伺服器,send發送訊息,等待處理,通訊完成後調用CloseSocket關閉Socket

服務端:建立Socket,聲明自身的連接埠號碼和地址並綁定到Socket,使用Listen開啟監聽,然後不斷用Accept去查看是否有串連,如果有,捕獲Socket,並通過Recv擷取訊息的內容,通訊完成後調用CloseSocket關閉這個對應Accept到的Socket,如果不再需要等待任何用戶端串連,那麼用CloseSocket關閉掉自身的Socket

 

程式碼範例

用戶端:這裡建立一個CLientNet類,用於表示一個客戶

 

#pragma once/*ClinetNet.h:用於表示一個客戶的網路操作*/#include <stdio.h>#include<windows.h>#pragma comment(lib, "Ws2_32.lib")class CClientNet{public://串連上指定伺服器int Connect(int port,const char* address);//發送資訊int SendMsg(const char* msg,int len);//關閉void Close();private:SOCKET m_sock;};

 

/*CLientNet.cpp*/#include "ClientNet.h"int CClientNet::Connect( int port,const char* address ){int rlt = 0;//用於記錄錯誤資訊並輸出int iErrMsg;//啟動WinSockWSAData wsaData;iErrMsg = WSAStartup(MAKEWORD(1,1),&wsaData);if (iErrMsg != NO_ERROR)//有錯誤{printf("failed with wsaStartup error : %d\n",iErrMsg);rlt = 1;return rlt;}//建立Socketm_sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if (m_sock == INVALID_SOCKET)//建立Socket失敗{printf("socket failed with error : %d\n",WSAGetLastError());rlt = 2;return rlt;}//目標伺服器資料sockaddr_in sockaddrServer;sockaddrServer.sin_family = AF_INET;sockaddrServer.sin_port = port;sockaddrServer.sin_addr.s_addr = inet_addr(address);//串連,sock與目標伺服器串連iErrMsg = connect(m_sock,(sockaddr*)&sockaddrServer,sizeof(sockaddrServer));if (iErrMsg < 0){printf("connect failed with error : %d\n",iErrMsg);rlt = 3;return rlt;}return rlt;}int CClientNet::SendMsg(const char* msg,int len){int rlt = 0;int iErrMsg = 0;//發送訊息,指定sock發送訊息iErrMsg = send(m_sock,msg,len,0);if (iErrMsg < 0)//發送失敗{printf("send msg failed with error : %d\n",iErrMsg);rlt = 1;return rlt;}return rlt;}void CClientNet::Close(){closesocket(m_sock);}

 

#include "ClientNet.h"void main(){CClientNet client;//串連到127.0.0.1(即本地),連接埠號碼為8888的服務端printf("Connect\n");client.Connect(8888,"127.0.0.1");//發送訊息printf("send msg\n");client.SendMsg("hello\0",sizeof("hello\0"));//關閉socketprintf("close\n");client.Close();system("pause");}

 

服務端代碼:

 

#pragma once/*ServerNet.h用於表示服務端的網路操作*/#include <stdio.h>#include <winsock.h>#pragma comment (lib,"ws2_32.lib")class CServerNet{public://初始化伺服器,返回0表示成功int Init(const char* address,int port);//更新資料void Run();private:SOCKET m_sock;};

 

/*ServerNet.cpp*/#include "ServerNet.h"int CServerNet::Init( const char* address,int port ){int rlt = 0;//用於記錄錯誤資訊,並輸出int iErrorMsg;//初始化WinSockWSAData wsaData;iErrorMsg = WSAStartup(MAKEWORD(1,1),&wsaData);if (iErrorMsg != NO_ERROR){//初始化WinSock失敗printf("wsastartup failed with error : %d\n",iErrorMsg);rlt = 1;return rlt;}//建立服務端Socketm_sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if (m_sock == INVALID_SOCKET){//建立Socket異常printf("socket failed with error : %d\n",WSAGetLastError());rlt = 2;return rlt;}//聲明資訊sockaddr_in serverAddr;serverAddr.sin_family = AF_INET;serverAddr.sin_port = port;serverAddr.sin_addr.s_addr = inet_addr(address);//綁定iErrorMsg = bind(m_sock,(sockaddr*)&serverAddr,sizeof(serverAddr));if (iErrorMsg < 0){//綁定失敗printf("bind failed with error : %d\n",iErrorMsg);rlt = 3;return rlt;}return rlt;}void CServerNet::Run(){//公開串連listen(m_sock,5);sockaddr_in tcpAddr;int len = sizeof(sockaddr);SOCKET newSocket;char buf[1024];int rval;do {//接收資訊newSocket = accept(m_sock,(sockaddr*)&tcpAddr,&len);if (newSocket == INVALID_SOCKET){//非可用socket}else{//新socket串連printf("new socket connect : %d\n",newSocket);//訊息處理do{printf("process\n");//接收資料memset(buf,0,sizeof(buf));rval = recv(newSocket,buf,1024,0);if (rval == SOCKET_ERROR)//這應該是個異常,當用戶端沒有調用closeSocket就直接離開遊戲的時候,將會進入這裡printf("recv socket error\n");if (rval == 0)//recv返回0表示正常退出printf("ending connection");else//顯示接收到的資料printf("recv %s\n",buf);}while(rval != 0);//關閉對應Accept的socketclosesocket(newSocket);}} while (1);//關閉自身的Socketclosesocket(m_sock);}

 

 

#include "ServerNet.h"int main(int argc, char **argv){CServerNet serverNet;int iRlt = serverNet.Init("127.0.0.1",8888);if (iRlt == 0){printf("init ok...\n");serverNet.Run();}elseprintf("serverNet init failed with error : %d\n",iRlt);system("pause");}

 

 

#pragma once/*ClinetNet:用於表示一個客戶的網路操作*/#include <stdio.h>#include<windows.h>#pragma comment(lib, "Ws2_32.lib")class CClientNet{public://串連上指定伺服器int Connect(int port,const char* address);//發送資訊int SendMsg(const char* msg,int len);//關閉void Close();private:SOCKET m_sock;};

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.