基於TCP(面向鏈接)的socket編程

基於TCP(面向鏈接)socket編程 編程

一.基於TCP(面向鏈接)的socker編程的服務器端程序流程以下: 服務器

(1)    建立套接字(socket 網絡

(2)    將套接字綁定到一個本地地址和端口上(bind socket

(3)    將套接字設置爲監聽模式,準備接收客戶請求(listen ide

(4)    等待客戶請求的到來;當客戶請求到來後,接受鏈接請求,返回一個新的對應於這次鏈接的套接字(accept 函數

(5)    用返回的套接字和客戶端進行通訊(send/recv spa

(6)    返回等待另外一個客戶請求 指針

(7)    關閉套接字 orm

. 基於TCP(面向鏈接)socket編程的客戶端程序流程以下: 隊列

1)建立套接字(socket

2)向服務器發出鏈接請求(connect

3)和服務器端進行通訊(send/recv

4)關閉套接字

 

 

例子:

服務器端:

  
  
  
  
  1. //服務器端  
  2.  
  3. #include <WINSOCK2.H>  
  4. #include <stdio.h>  
  5.  
  6. void main()  
  7. {  
  8. /********************************************************    在利用套接字編程時,首先要加載套接字,經過WSAStartup函數來實現.  
  9.     函數原型:int WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData);  
  10.        (1) wVersionRequested:用來指定準備加載的Winsock庫的版本,高位字節指定所需的winsock庫的副版本,低位字節則是主版本。能夠利用MAKEWORD(x, y)宏來得到wVersionRequested的正確值。  
  11.         (2) lpWSAData是指向WSADATA結構的指針,WSAStartup函數用其加載的庫版本有關的信息填充在這個結構中  
  12. ***********************************************/ 
  13.       
  14.     WORD wVersionRequested;  
  15.     WSADATA wsaData;  
  16.     int err;  
  17.  
  18.     wVersionRequested = MAKEWORD(1, 1);  
  19.     err = WSAStartup(wVersionRequested, &wsaData);  
  20.  
  21.     if(err != 0)  
  22.     {  
  23.         //加載失敗  
  24.         return;  
  25.     }  
  26.  
  27.     if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)  
  28.     {  
  29.         //釋放爲該應用程序分配的資源,終止對WinSock動態庫的使用  
  30.         WSACleanup();  
  31.         return;  
  32.     }  
  33.  
  34.     /*************************************************************************************/ 
  35.     /*  加載套接字庫以後,調用socket函數建立套接字  
  36.     函數原型:SOCKET socket(int af, int type,  int protocol);  
  37.     (1):af參數指定地址族,對於TCP/IP協議的套接字,它只能是AF_INET(也能夠寫成PF_INET)  
  38.     (2):type參數,指定socket類型,對於1.1版本的socket,只支持兩種:SOCK_STREAM, SOCK_DGRAM  
  39.     (3):protocol參數是與特定的地址家族相關的協議,推薦指定爲0  
  40.     返回值:若是socket函數調用成功,返回一個新的socket數據類型的套接字描述符,若是調用失敗,  
  41.             此函數返回一個INVALID_SOCKET值,錯誤信息經過WSAGetLastError函數返回  
  42.     */ 
  43.     /************************************************************************************/ 
  44.       
  45.       
  46.     //建立用於監聽的套接字  
  47.     SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);  
  48.  
  49.  
  50.     /**************************************************************************************************************/ 
  51.     /* 經過bind函數將套接字綁定到本地的某個地址和端口上  
  52.        函數原型:int bind(SOCKET s, const struct sockaddr FAR *name, int namelen);  
  53.        (1)s參數指定要綁定的套接字。  
  54.        (2)name參數指定了該套接字的本地地址信息,此爲一個指向sockaddr結構的指針變量  
  55.        (3)namelen參數指定該地址結構的長度  
  56.        備註1:struct sockaddr{  
  57.                 u_short sa_family;  //指定地址家族,對TCP/IP協議的套接字,必須爲AF_INET  
  58.                 char    sa_data[14]; //僅表示要求一塊內存分配區,起到佔位的做用,該區域中指定與協議相關的具體地址信息  
  59.                 };  
  60.         在基於TCP/IP的socket編程中,使用sockaddr_in結構替換sockaddr  
  61.              struct sockaddr_in{  
  62.                 short             sin_family; //指定地址家族,對TCP/IP協議的套接字,必須爲AF_INET  
  63.                 unsigned short    sin_port;   //指定分配給套接字的端口,必須爲網絡字節序  
  64.                 struct   in_addr  sin_addr;   //指定套接字的主機IP地址,必須爲網絡字節序  
  65.                 char              sin_zero[8];//起佔位做用  
  66.                 };  
  67.                 其中sin_addr成員的類型是in_addr,該結構定義以下:  
  68.                 struct in_addr{  
  69.                     union {  
  70.                        struct { u_char s_b1,s_b2,s_b3,s_b4; }   S_un_b; //Address of the host formatted as four u_chars.   
  71.                        struct { u_short s_w1,s_w2; }            S_un_w; //Address of the host formatted as two u_shorts.   
  72.                        u_long                                   S_addr; //Address of the host formatted as a u_long.   
  73.                        } S_un;  
  74.                 };  
  75.  
  76.         備註2:(1)  u_short htons(u_short hostshort );  
  77.                     此函數用於將一個u_short類型的值從主機字節順序轉換爲TCP/IP網絡字節順序。  
  78.                (2)  u_long  htonl(u_long  hostlong  );  
  79.                     此函數用於將一個u_long類型的值從主機本身順序轉換爲TCP/IP網絡字節順序。  
  80.                (3)  unsigned long inet_addr(const char   FAR *cp);  
  81.                     此函數須要一個字符串做爲其參數,該字符串指定了以點分十進制格式表示的IP地址,返回一個適合分配給S_addr的u_long類型的數值  
  82.                (4)  char FAR * inet_ntoa(struct   in_addr in);  
  83.                     此函數接受一個in_addr結構體類型的參數並返回一個以點分十進制格式表示的IP地址字符串  
  84.     */ 
  85.     /******************************************************************************************************************/ 
  86.  
  87.     SOCKADDR_IN addrSrv;  
  88.     addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//將u_short類型的值從主機字節序轉換位網絡字節序  
  89.     addrSrv.sin_family = AF_INET;  
  90.     addrSrv.sin_port = htons(6001); //將u_long類型的值從主機字節序轉換爲網絡字節序  
  91.     //綁定套接字  
  92.     bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));  
  93.  
  94.  
  95.     /************************************************************************/ 
  96.     /* 將指定的套接字設置爲監聽模式  
  97.        函數原型:int listen(SOCKET s,    int backlog);  
  98.        (1): s參數是套接字描述符  
  99.        (2): backlog參數是等待鏈接隊列的最大長度  
  100.     */ 
  101.     /************************************************************************/ 
  102.     //將套接字設爲監聽模式,準備接收客戶請求  
  103.     listen(sockSrv, 5);  
  104.  
  105.     SOCKADDR_IN addrClient;  
  106.     int len = sizeof(SOCKADDR);  
  107.  
  108.     while (1)  
  109.     {  
  110.         /************************************************************************/ 
  111.         /* 利用accept函數接受客戶端發送的請求  
  112.         函數原型:SOCKET accept(SOCKET s, struct sockaddr FAR *addr,  int FAR *addrlen);  
  113.         (1) s參數是套接字描述符,該套接字已經經過listen函數將其設置爲監聽狀態  
  114.         (2) addr參數指向一個緩衝區的指針,該緩衝區用來接收鏈接實體的地址,即客戶端的IP地址和端口  
  115.         (3) addrlen參數指向一個整型的指針,返回包含地址信息的長度  
  116.         */ 
  117.         /************************************************************************/ 
  118.  
  119.         //等待客戶請求  
  120.         SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &len);  
  121.           
  122.         char sendBuf[100];  
  123.         sprintf(sendBuf,"Welcome %s to xidian", inet_ntoa(addrClient.sin_addr));  
  124.         printf("Welcome %s to xidian\n", inet_ntoa(addrClient.sin_addr));  
  125.  
  126.         //發送數據  
  127.         send(sockConn, sendBuf, strlen(sendBuf)+1, 0);  
  128.  
  129.         char recvBuf[100]={'0'};  
  130.         //接收數據  
  131.         recv(sockConn, recvBuf, 100, 0);  
  132.  
  133.         //打印接收的數據  
  134.         printf("%s\n", recvBuf);  
  135.         //關閉套接字  
  136.         closesocket(sockConn);  
  137.     }  
  138.       

 客戶端:

 

  
  
  
  
  1. //TCP客戶端  
  2.  
  3. #include <WINSOCK2.H>  
  4. #include <stdio.h>  
  5.  
  6. void  main()  
  7. {  
  8.     //加載套接字庫  
  9.     WORD wVersionRequested;  
  10.     WSADATA wsaData;  
  11.     int err;  
  12.  
  13.     wVersionRequested = MAKEWORD(1, 1);  
  14.       
  15.     err = WSAStartup(wVersionRequested, &wsaData);  
  16.     if (err != 0)  
  17.     {  
  18.         return;  
  19.     }  
  20.  
  21.     if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)  
  22.     {  
  23.         WSACleanup();  
  24.         return;  
  25.     }  
  26.  
  27.  
  28.     //建立套接字  
  29.     SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);  
  30.  
  31.     //要鏈接服務器的信息,注意使用的是網絡字節序  
  32.     SOCKADDR_IN addrSrv;  
  33.     addrSrv.sin_family = AF_INET;  
  34.     addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");  
  35.     addrSrv.sin_port = htons(6001);  
  36.  
  37.  
  38.     //向服務器發送鏈接請求  
  39.     connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));  
  40.  
  41.     //接收數據  
  42.     char recvBuf[100]={'0'};  
  43.  
  44.     recv(sockClient, recvBuf, 100, 0);  
  45.  
  46.     printf("%s\n", recvBuf);  
  47.  
  48.     //發送數據  
  49.     send(sockClient, "This is a client test", strlen("This is a client test")+1, 0);  
  50.  
  51.     //關閉套接字  
  52.     closesocket(sockClient);  
  53.     WSACleanup();  
  54.  
相關文章
相關標籤/搜索