VC++ socket通信實例 總結

1.        兩天計算機通信需要協議,通信的兩臺計算機IP必須唯一

2.        同一個計算機可以進行多個應用程序與其他計算機通信,IP地址唯一,而端口號是區別同一計算機(同一IP)的唯一標示。

3.        實際上就類似於一個辦公室的總機號碼(IP)和分機號碼(端口號)

4.        協議:爲了進行網絡中的數據交換(通信)而建立的規則、標準或約定

5.        協議=語義+語法+規則

6.        不同層具有各自不同的協議

7.        上層使用下層提供的服務,實際通信在最底層完成

8.        對等層實體之間虛擬通信|

9.        TCP:面向連接的可靠的傳輸協議

10.    UDP:面向無連接的不可靠的傳輸協議

11.    端口是一種抽象的軟件結構。應用程序通過系統調用與某端口建立連接後,傳輸層傳給端口的數據都被響應的進行所接收,相應進程發給傳輸層的數據都通過該端口輸出。

12.    端口用一個整數型標示符來表示。端口號跟協議相關,TCP/IP傳輸層的兩個協議TCP和UDP是完全獨立的兩個軟件模塊,因此各自的端口號也相互獨立。

13.    端口使用一個16位的數字來表示,它的範圍是0~65535,1024以下的端口號保留給預定義的服務。例如:http使用的是80端口。

14.    socket(套接字):windows sockets只支持一個通信區域:網際域(AF_INET),這個域被使用網際協議簇通信的進程使用。

15.    C/S模式:客戶機向服務器提出請求,服務器接收到請求後,提供相應的服務。

16.    套接字的類型

a)        流式套接字:(SOCK_STREAM):面向連接可靠的數據傳輸服務,按順序接收

b)       數據包式套接字:(SOCK_DGRAM):無連接服務。接收順序混亂。

c)       原始套接字(SOCK_RAM)

17.    基於TCP(面向連接)的socket編程

a)        服務器端程序:

                        i.             創建套接字socket

                      ii.             將套接字綁定到一個本地地址和端口上bind

                     iii.             將套接字設爲監聽模式,準備接收客戶請求listen

                    iv.             等待客戶請求到了;當請求到來後,接收連接請求,返回一個新的對應於此次連接的套接字accept

                      v.             用返回的套接字和客戶端進行通信rend/recv

                    vi.             返回,等待另一客戶請求

                   vii.             關閉套接字

b)       客戶端程序:

                        i.             創建套接字socket

                      ii.             向服務端發出連接請求connect

                     iii.             和服務器端進行通信rend/recv

                    iv.             關閉套接字

18.    基於UDP的socket編程

a)        服務器端(接收端)程序:

                        i.             創建套接字socket

                      ii.             將套接字綁定到一個本地地址和端口上bind

                     iii.             等待接收數據recv/from

                    iv.             關閉套接字

b)       客戶端(發送端)程序:

                        i.             創建套接字socket

                      ii.             向服務器發送數據sendto

                     iii.             關閉套接字

19.    int WSAStartup (

  WORD wVersionRequested, //打算使用的最高winsock版本號 
  LPWSADATA lpWSAData  //是個結構體,接收socket的詳細信息
);

20.    alt+F8:格式化代碼

21.    面向TCP的連接,服務器端

a)        套接字

SOCKET socket (
  int af,       //指定地址簇
  int type,     //socket類型
  int protocol  //協議

);

b)       綁定

int bind (
  SOCKET s,                          //要綁定的套接字
  const struct sockaddr FAR*  name,  //指定了該套接字的本地地址信息
  int namelen                        //該地址結構的長度
);

struct sockaddr {

       u_short    sa_family;

       char       sa_data[14];

};

c)       監聽

int listen (
  SOCKET s,    
  int backlog  
);

d)       接受連接

SOCKET accept (
  SOCKET s,                   
  struct sockaddr FAR* addr
  int FAR* addrlen            
);
e)      發送
int send (
  SOCKET s,              //建立連接的socket
  const char FAR * buf,  //發送的數據
  int len,               //發送數據的長度
  int flags              
);
f)      接收
int recv (
  SOCKET s,       
  char FAR* buf
  int len,        
  int flags       
);
g)      需要的文件
#include <winsock2.h>
需要連接一個動態鏈接庫:ws2_32.lib

22.    服務器端:

a)        Socket

b)       連接:connect

 int connect (
  SOCKET s,                          
  const struct sockaddr FAR*  name
  int namelen                        
);

c)       接收:recv

d)       發送:send

e)        關閉:closesocket

23.    Tcp服務端程序:

#include <WINSOCK2.H>
#include <stdio.h>
void main()
{
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;
	
	wVersionRequested = MAKEWORD( 1, 1 );
	
	err = WSAStartup( wVersionRequested, &wsaData );
	if ( err != 0 ) {
		return;
	}
	
	if ( LOBYTE( wsaData.wVersion ) != 1 ||
        HIBYTE( wsaData.wVersion ) != 1 ) {
		WSACleanup( );
		return; 
	}
	SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);

	SOCKADDR_IN addrSrv;
	addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
	addrSrv.sin_family=AF_INET;
	addrSrv.sin_port=htons(6000);

	bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

	listen(sockSrv,5);

	SOCKADDR_IN addrClient;
	int len=sizeof(SOCKADDR);

	while(1)
	{
		SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
		char sendBuf[100];
		sprintf(sendBuf,"Welcome %s to 劉窪村",inet_ntoa(addrClient.sin_addr));
		send(sockConn,sendBuf,strlen(sendBuf)+1,0);
		char recvBuf[100];
		recv(sockConn,recvBuf,100,0);
		printf("%s\n",recvBuf);
		closesocket(sockConn);
		
	}

}

24.    Tcp客戶端程序:

#include <WINSOCK2.H>
#include <stdio.h>
void main()
{
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;
	
	wVersionRequested = MAKEWORD( 1, 1 );
	
	err = WSAStartup( wVersionRequested, &wsaData );
	if ( err != 0 ) {
		return;
	}
	
	if ( LOBYTE( wsaData.wVersion ) != 1 ||
        HIBYTE( wsaData.wVersion ) != 1 ) {
		WSACleanup( );
		return; 
	}
	SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);

	SOCKADDR_IN addrSrv;
	addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");//服務器端的地址
	addrSrv.sin_family=AF_INET;
	addrSrv.sin_port=htons(6000);
	connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

	char recvBuf[100];
	recv(sockClient,recvBuf,100,0);
	printf("%s\n",recvBuf);
	send(sockClient,"This is 劉窪村",strlen("This is 劉窪村")+1,0);

	closesocket(sockClient);
	WSACleanup();
}

25.    運行之後,開啓了6個客戶端,一個服務器端。程序運行效果:

26.    面向UDP的連接

27.    服務器:socket

a)        bind

b)       接收數據:

int recvfrom (
  SOCKET s,                   //套接字
  char FAR* buf,              //接收數據
  int len,                    //長度
  int flags,                  //會影響調用行爲,0
  struct sockaddr FAR* from,  //接收發送方的地址信息
  int FAR* fromlen            //接收長度
);

c)       關閉closesocket

d)       Cleanup

28.    UDP服務器端程序:

#include <WINSOCK2.H>
#include <stdio.h>

void main()
{
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;
	
	wVersionRequested = MAKEWORD( 1, 1 );
	
	err = WSAStartup( wVersionRequested, &wsaData );
	if ( err != 0 ) {
		return;
	}
	
	if ( LOBYTE( wsaData.wVersion ) != 1 ||
        HIBYTE( wsaData.wVersion ) != 1 ) {
		WSACleanup( );
		return; 
	}

	SOCKET sockSrv=socket(AF_INET,SOCK_DGRAM,0);
	SOCKADDR_IN addrSrv;
	addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
	addrSrv.sin_family=AF_INET;
	addrSrv.sin_port=htons(6000);

	bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

	SOCKADDR_IN addrClient;
	int len=sizeof(SOCKADDR);
	char recvBuf[100];

	recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrClient,&len);
	printf("%s\n",recvBuf);
	closesocket(sockSrv);
	WSACleanup();

}

28.    UDP客戶端:

a)        socket定義

b)       發送:

   int sendto (
  SOCKET s,                        
  const char FAR * buf,            
  int len,                         
  int flags,                       
  const struct sockaddr FAR * to
  int tolen                        
);

 29.  UDP客戶端程序

#include <WINSOCK2.H>
#include <stdio.h>

void main()
{
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;
	
	wVersionRequested = MAKEWORD( 1, 1 );
	
	err = WSAStartup( wVersionRequested, &wsaData );
	if ( err != 0 ) {
		return;
	}
	
	if ( LOBYTE( wsaData.wVersion ) != 1 ||
        HIBYTE( wsaData.wVersion ) != 1 ) {
		WSACleanup( );
		return; 
	}
	
	SOCKET sockClient=socket(AF_INET,SOCK_DGRAM,0);
	SOCKADDR_IN addrSrv;
	addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
	addrSrv.sin_family=AF_INET;
	addrSrv.sin_port=htons(6000);

	sendto(sockClient,"Hello 劉窪村",strlen("Hello 劉窪村")+1,0,
		(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
	closesocket(sockClient);
	WSACleanup();
}
運行結果:

30.  注意:每個程序都要加上ws2_32.lib鏈接庫。如下添加:



                                      By  劉窪村

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章