久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 8019|回復: 0
收起左側

基于TCP和UDP的Socket編程

[復制鏈接]
ID:51090 發表于 2014-9-18 12:55 | 顯示全部樓層 |閱讀模式
在OSI的各層所使用的協議:
1.應用層:telnet,FTP,HTTP,DNS,SMTP,POP3
2.傳輸層:TCP,UDP
      TCP:面向連接的可靠的傳輸協議,通信前建立三次握手,握手成功后才能通信,對數據準確性要求較高的場合使用,如從網上載的安裝文件,不能缺少任何信息
      UDP:是無連接的,不可靠的傳輸協議,不需要建立連接,也沒有重傳和確認的機制,在實時性要求較高,但對數據準確度要求不是很高的場合使用,如視頻會議,在線觀看電影,當中丟失個別數據包并不影響整體的效果。
3.網絡層:IP

因為OSI七層結構較為復雜,所以使用較多的是TCP/IP模型,現在TCP/IP已經成為Internet上通用的工業標準
TCP/IP模型包括4個層次:應用層,傳輸層,網絡層,網絡接口

端口:
1.      為了標識通信實體中進行通信的進程(應用程序),TCP/IP協議提出了協議端口的概念
2.      端口是一種抽象的軟件結構(包括一些數據結構和I/O緩沖區)。應用程序通過系統調用和某端口建立連接(binding)后,傳輸層傳給該端口的數據都被相應的進程所接收,相應進程發給傳輸層的數據都通過該端口輸出
3.      端口用一個整數型標識符來表示,即端口號。端口號跟協議相關,TCP/IP傳輸層的兩個協議TCP和UDP是完全獨立的的兩個軟件模塊,因此各自的端口號也相互獨立
4.      端口使用一個16位的數字來表示,它的范圍是0~65535,1024以下的端口號保留給預定義的服務,例如,http使用80端口

套接字(Socket)
1.      Socket的出現,使得程序員可以很方便的訪問TCP/IP,從而開發各種網絡應用的程序
2.      套接字存在于通信區域中,通信區域也叫地址族,他是一個抽象的概念,主要用于通過套接字通信的進程的共有特性綜合在一起。套接字通常只與同一個區域的套接字交換數據。

套接字的類型
1.      流式套接字(SOCK_STREAM)
提供面向連接的,可靠的數據傳輸服務,數據無差錯,無重復的發送,且按發送的順序接收,基于TCP協議
2.      數據保式套接字(SOCK_DGRAM)
提供無連接的服務,數據包以獨立包形式發送,不提供無錯誤的保證,數據可能丟失或重復,且接收順序混亂,基于UDP協議

基于TCP(面向連接)的Socket編程
服務器端順序:
1.      加載套接字庫
2.      創建套接字(socket)
3.      將套接字綁定到一個本地地址和端口上(bind)
4.      將套接字設為監聽模式,準備接收客戶請求(listen)
5.      等待客戶請求的到來;當請求帶來后,接受連接請求,返回一個新的對應于此次連接的套接字(accept)
6.      用返回的套接字和客戶端進行通信(send/recv)
7.      返回,等待另一個客戶請求
8.      關閉套接字(closesocket)

客戶端程序:
1.      加載套接字庫
2.      創建套接字(socket)
3.      向服務器發送連接請求(connect)
4.      和服務器端進行通信(send/receive)
5.      關閉套接字(closesocket)

基于UDP(面向無連接)的socket編程
服務器端(接收端)程序:
1.      加載套接字庫
2.      創建套接字(socket)
3.      將套接字綁定到一個本地地址和端口上(bind)
4.      等待接收數據(recvfrom)
5.      關閉套接字(closesocket)

客戶端(發送端)程序
1.      加載套接字庫
2.      創建套接字(socket)
3.      向服務器發送數據(sendto)
4.      關閉套接字(closesocket)

創建基于TCP協議的CS程序的Server端所涉及的相關函數說明(按使用的先后順序排列):
1.     int WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData):作用是加載套接字庫和進行套接字庫的版本協商
a. 參數wVersionRequested:用于指定準備加載的Winsock庫的版本,高位字節指定所需要的Winsock庫的副版本,低位字節則是主版本,可用MAKEWORD(X,Y)(其中,x為高位字節,y為低位字節)方便獲得wVersionRequested的正確值。
b. 參數lpWSAData:指向WSADATA結構的指針,WSAStartup用其加載的庫版本有關的信息填在這個結構中
2.     SOCKET socket(int af,int type,int protocol):
a.      參數af指定地址族,對于TCP/IP協議的套接字,它只能是AF_INET(也可寫成PF_INET)。
b.      參數type指定Socket類型,對于1.1版本的Socket,它只支持兩種類型的套接字,SOCK_STREAM指定產生流式套接字,SOCK_DGRAM產生數據報套接字。
c.      參數protocol與特定的地址家族相關的協議,如果指定為0,那么他就會根據地址格式和套接字類別,自動為你選擇一個合適的協議。這是推薦使用的一種選擇協議的方式。
3.     int bind(SOCKET s,const struct sockaddr FAR *name,int namelen) :
a.      第一個參數指定要綁定的套接字,第二個參數指定該套接字的本地地址信息,是指向sockaddr結構的指針變量,由于該地址結構是為了所有的地址家族準備使用的,這個結構可能(通常會)隨使用的網絡協議不同而不同,所以,要用第三個參數指定該地址結構的長度。sockaddr機構定義如下:
struct sockaddr
{
      u_short sa_family;
      char sa_data[14];
}
b.      上述結構第一個字段指定該地址家族,在這里必須設為AF_INET。sa_data僅僅是表示要求一塊內存分配區,起到占位的作用,該區域中指定與協議相關的具體地址信息。由于實際要求的只是內存區,所以對于不同的協議家族,用不同的結構來替換sockaddr。在TCP/IP中,我們可以用SOCKADDR_IN結構來代替sockaddr,以方便我們填寫地址信息。
c.      struct SOCKADDR_IN{
    short sin_family;
    unsigned short sin_port;
    struct in_addr sin_addr;
    char sin_zero[8];
};
sin_family表示地址族,對于IP地址,sin_family成員將一直是AF_INET;成員sin_port指定的將要分配給套接字的端口;成員sin_addr給出的是套接字的主機IP地址;sin_zero只是一個填充數,以使sockaddr_in結構和sockaddr結構的長度一樣,一般不用設置。
除了sin_family外,SOCKADDR_IN其他成員是按網絡字節順序表示的。所以需要進行轉換:htonl(INADDR_ANY),htons(6000),其中6000是端口號。
另外結構體的名稱大寫和小寫指的是同一個。
將IP地址指定為INADDR_ANY,允許套接字向任何分配給本機器的IP地址發送或接收數據。一般一臺機器一個網卡,但對于多網卡的機器,INADDR_ANY將簡化應用程序的編寫。將地址指定為INADDR_ANY,允許一個獨立的應用接受發自多個接口的回應。如果我們只想讓套接字使用多個IP中的一個地址,必須指定實際地址,要做到這一點,可以用inet_addr()函數,這個函數需要一個IP地址(如192.168.80.88),返回一個適合分配給S_addr的u_long類型的數值。Inet_ntoa()函數完成相反的轉換,它接受一個in_addr結構體類型的參數并返回一個以點分十進制的IP地址字符串。
htonl把一個u_long類型從主機字節序轉換為網絡字節序。
htons把一個u_short類型從主機字節序轉換為網絡字節序。
4.     int listen(SOCKET s, int backlog):將套接字設置為監聽模式,其中第二個參數設置等待請求連接的最大的值,即如果設置為n,則前n個請求會放置在系統的請求連接隊列中,應用程序會依次對這些請求進行服務,但第n+1個連接請求則會被拒絕。
5.     SOCKET accept(SOCKET s, const struct sockaddr FAR * addr, int FAR* addrlen):
從客戶端接收請求,并創建連接,如果連接成功,則會返回一個當前成功建立連接的套接字,該套接字不是上面創建的監聽套接字,而是僅僅適用于當前的一個請求連接,如果建立連接失敗,則返回值是INVALID_SOCKET,并且可以適用WSAGetLastError()函數得到相關的失敗信息,具體的error code具體意義見MSDN中accept函數的最后部分的介紹
6.     send 函數:向客戶端發送指定信息
7.     recv函數:得到從客戶端傳遞過來的信息
8.     closesocket(SOCKET s):將指定的套接字關閉,從而釋放資源
9.     WSACleanup():終止對winsocket庫的使用
10. hello

服務器端的實現過程(Win32控制臺程序):
說明:
1.      對于winsock庫的類的使用,必須包含winsock2.h頭文件
2.      在setting中的link下的object/library modules中添加“ws2_32.lib”,注意和前面的字段之間用空格分隔
3.      本服務器程序先于服務器端啟動
#include "winsock2.h"
#include "stdio.h"
void main()
{
      //加載套接字(winsock)庫,加載這段代碼拷貝于MSDN中WSAStartup的介紹
      WORD wVersionRequested;
      WSADATA wsaData;
      int err;     
      wVersionRequested = MAKEWORD( 1, 1 ); //版本號為1.1
       err = WSAStartup( wVersionRequested, &wsaData );
      if ( err != 0 ) {                              
           return;
      }                                    

      if ( LOBYTE( wsaData.wVersion ) != 1 ||
        HIBYTE( wsaData.wVersion ) != 1 ) {
           WSACleanup( );
           return;
      }

      //創建套接字
      SOCKET sockServer=socket(AF_INET,SOCK_STREAM,0); //SOCK_STREAM參數設置為TCP連接
      SOCKADDR_IN addrServer; //設置服務器端套接字的相關屬性
      addrServer.sin_addr.S_un.S_addr=htonl(INADDR_ANY); //設置IP
      addrServer.sin_family=AF_INET;
      addrServer.sin_port=htons(1234); //設置端口號

      //將套接字綁定到本地地址和指定端口上
      bind(sockServer,(SOCKADDR*)&addrServer,sizeof(SOCKADDR));

      //將套接字設置為監聽模式,并將最大請求連接數設置成5,超過此數的請求全部作廢
      listen(sockServer,5);

      SOCKADDR_IN addrClient; //用來接收客戶端的設置,包括IP和端口
      int len=sizeof(SOCKADDR);
      while(1) //不斷監聽
      {
           //得到創建連接后的一個新的套接字,用來和客戶端進行溝通,原套接字繼續監聽客戶的連接請求
           SOCKET sockConn=accept(sockServer,(SOCKADDR*)&addrClient,&len);
            if(sockConn!=INVALID_SOCKET) //創建成功
           {
                 char sendInfo[100];
                 //inet_ntoa將結構轉換為十進制的IP地址字符串
sprintf(sendInfo,"welcome %s to this test!",inet_ntoa(addClient.sin_addr));
                 //成功建立連接后向客戶端發送數據,結果將顯示在客戶端上
                 send(sockConn,sendInfo,strlen(sendInfo)+1,0);

                 //從客戶端接收數據,結果顯示在服務器上
                 char recvInfo[100];
                 recv(sockConn,recvInfo,100,0);
                 printf("%s\n",recvInfo);

                 //將本次建立連接中得到套接字關閉
                 closesocket(sockConn);
           }
           else
           {
                 int errCode=WSAGetLastError();
                 printf("the errcode is:%d\n",errCode);
           }         
      }
      //如果本程序不是死循環,那么在此處還應添加以下代碼:
      closesocket(sockServer); //對一直處于監聽狀態的套接字進行關閉
      WSACleanup(); //終止對winsocket庫的使用     
}

回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久69精品久久久久久久电影好 | 精品国产乱码一区二区三区a | 美女在线观看av | av黄色免费 | 一区二区三区中文字幕 | 欧美日韩电影一区二区 | 日韩欧美专区 | 中文字字幕一区二区三区四区五区 | 久久91 | 久久久国产一区 | 日韩在线欧美 | 亚洲成人高清 | 国产激情偷乱视频一区二区三区 | 日韩在线免费视频 | 992人人草 | 国产成人综合久久 | 国产视频一视频二 | 在线观看成人 | 亚洲欧洲中文 | 亚洲国产成人在线视频 | 久久99精品久久久久婷婷 | 婷婷色成人 | 日韩有码一区二区三区 | 天堂精品 | 一级一级毛片免费看 | 午夜精品久久久久久 | 99热国产精品 | 久草色播| 久久精品久久久久久 | 亚洲一区亚洲二区 | 日本午夜精品 | 国产在线第一页 | 国产精品美女久久久久久免费 | 麻豆久久久久久 | 亚洲狠狠 | 日韩精品视频一区二区三区 | 久久久精品久久 | 免费看黄视频网站 | 在线观看黄色电影 | 成年免费大片黄在线观看岛国 | 午夜精品一区二区三区在线观看 |