MFC UDP通訊的簡單實現

2021-07-03 23:20:00 字數 3622 閱讀 6205

1. udp和tcp最大的區別:

1) tcp最大的特點就是面向連線、安全可靠,也就是說tcp通訊必須要先建立連線,並且通訊過程需要時時校驗,如果資料有誤需要重發;

2) udp最大的特點就是面向無連線,不可靠,也就是說不用建立連線就直接向目標傳送資訊,並且通訊過程中不做任何校驗,如果資料丟失或者有誤也不管;

2. udp的sockets程式設計:

1) 首先最大的特點就是客戶端不需要使用connect連線,伺服器端也不需要listen來監聽請求,但不過建立套接字的過程還是和tcp一樣的;

2) 伺服器端不需要accept了,因為不需要監聽,而是直接可以用recvfrom函式接受客戶端傳送的資料!

3) 而客戶端由於不需要connect連線伺服器端,因此可以直接使用sendto函式向目標伺服器傳送資料;

4) 雙方都可以直接使用sendto和recvfrom進行資料通訊;

5) udp套接字的配置:

i. 首先需要在socket()函式中指定為sock_dgram,即資料報套接字型別(基於udp);

ii. 在tcp中,資料收發必須持有對方的套接字,而伺服器端監聽、接收請求必須持有本地的套接字,一般需要兩個套接字來支援;

iii. 但是在udp中,通訊雙方只能持有乙個套接字,即都是本地的套接字,傳送的時候需要指定對方的套接字位址,而接收的時候需要用乙個空的套接字位址接收對方的位址,即收發時sendto和recvfrom中的套接字控制代碼s都是繫結了本地位址的套接字,收發統統必須持有自己的套接字;

iv. 也就是說資料收發的快取都是用本地套接字!而tcp中資料收發的快取都是用對方的套接字(建立在本地程式中);

v. 因此,雙方在收發資料之前必須先對本地位址進行繫結,伺服器端仍然可以使用bind進行顯示的繫結,但是在winsock手冊中明確講了不支援在客戶端中使用bind來顯示繫結自己的位址,因為顯示繫結往往需要你輸入精確的位址,而有些時候位址是動態分配的,每次使用的都可能不一樣,因此不推薦在客戶端中顯示的使用bind來繫結自己的位址;

vi. 還好,sendto函式在第一次呼叫的時候就能隱式地繫結當前的位址,由於伺服器端只能被動地等待請求,因此不可能比recvfrom先呼叫sendto,所以伺服器端要先使用bind來繫結本地位址,而客戶端必須主動請求向伺服器端傳送資訊,因此不肯能比sendto先呼叫recvfrom,因此sendto一定先呼叫,而呼叫的同時也自動繫結了本地位址了;

6) sendto:

i. 函式原型:

int sendto(

socket s, // 繫結中本地位址的套接字

const char far* buf, // 傳送資料的快取

int len, // 資料的長度(位元組)

int flags, // 函式呼叫模式,一般為0

const struct sockaddr far* to, // 目標位址

int tolen, // 目標位址結構的大小

);

ii. 該函式將返回實際傳送的位元組數,當然可能小於指定的位元組數,如果失敗則會返回相應的錯誤碼;

7) recvfrom:

i. 函式原型:

int recvfrom(

socket s, // 繫結本地位址的套接字

char far* buf, // 接受資料的快取

int len, // 接受多少位元組

int flags, // 一般為0

struct sockaddr far* from, //用於接受資料來源的位址

int far* fromlen // 資料來源的位址的大小(位元組)

);

ii. 該函式將返回實際收到的位元組數,如果套接字被正常關閉將返回0,否則將返回錯誤碼;

!!下面將演示乙個簡單的udp通訊例項,實現的內容和上乙個tcp通訊例項一樣;

伺服器端:

#include #include #include #pragma comment(lib, "ws2_32.lib")

int main() ;

wsadata data;

word wversionrequired = makeword(2, 0);

wsastartup(wversionrequired, &data);

socket s = socket(af_inet, sock_dgram, 0);

sockaddr_in addr;

addr.sin_family = af_inet;

addr.sin_port = htons(75);

addr.sin_addr.s_un.s_addr = inaddr_any;

bind(s, (sockaddr*)&addr, sizeof(addr));

printf("server is setup and now waiting for clients' request...\n");

sockaddr_in addrclient;

int nsockaddrsize = sizeof(addrclient);

if (recvfrom(s, szbuff, sizeof(szbuff), 0, (sockaddr*)&addrclient, &nsockaddrsize) > 0)

closesocket(s);

wsacleanup();

if (getchar()) return 0;

return 0;

}

客戶端:

#include #include #include #pragma comment(lib, "ws2_32.lib")

int main() ;

wsadata data;

word wversionrequested = makeword(2, 0);

wsastartup(wversionrequested, &data);

socket s = socket(af_inet, sock_dgram, 0);

sockaddr_in addr;

addr.sin_family = af_inet;

addr.sin_port = htons(75);

addr.sin_addr.s_un.s_addr = inet_addr("127.0.0.1");

printf("client is setup and now trying to connect server...\n");

sockaddr_in addrserver;

int nsockaddrsize = sizeof(addrserver);

sendto(s, szsendtoserver, sizeof(szsendtoserver), 0, (sockaddr*)&addr, nsockaddrsize);

recvfrom(s, szbuff, sizeof(szbuff), 0, (sockaddr*)&addrserver, &nsockaddrsize);

printf("%s\n", szbuff);

closesocket(s);

wsacleanup();

if (getchar()) return 0;

return 0;

}

MFC TCP通訊的簡單實現

以下演示的是乙個使用tcp協議的客戶端和伺服器端實現 即流式套接字 客戶端請求連線,伺服器端回送給客戶端一句話 1.伺服器端 include include include pragma comment lib,ws2 32.lib 如果沒有ws2 32.dll則顯示鏈結靜態庫!int main 關...

UDP通訊的簡單實現(程式)

資訊處理介面,定義了資訊的關閉,傳送,和接收 public inte ce messageaction udp類實現了messageaction封裝了下面的資訊,並提供了相應的get和set方法private int sendport 要傳送資料的埠號埠號 private int localport...

通訊錄的簡單實現!!!

1.因為程式 較多,為了避免程式過於繁雜,將程式分成了兩個.c檔案 contact.c 和 test.c 和乙個contact h檔案。2.cantact.h檔案內容主要包括函式名和結構體的定義。3.contact.c檔案主要用於定義函式的實現,而test.c則主要起到測試的作用1.contact ...