udp和tcp的区别

区别

  • udp-无连接,数据报,不安全不可靠不稳定
  • tcp-面向连接,数据流,安全可靠稳定

udp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// Server.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <iostream>
using namespace std;
#define WIN32_LEAN_AND_MEAN//仅保留windows.h中的必要的头文件
//如果不加这一行则要把Winsock2.h放到windows.h前面,否则会因重定义而报错
#include <windows.h>
#include <Winsock2.h>
#pragma comment(lib,"Ws2_32.lib")

int main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{
return 0;
}

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

SOCKET sockServer = socket(AF_INET, SOCK_DGRAM , IPPROTO_UDP);
if (sockServer == INVALID_SOCKET)
{
cout << "socket 失败" << endl;
return 0;
}
//127.0.0.1-回环地址
sockaddr_in si;
si.sin_family = AF_INET;
si.sin_port = htons(0x7788);
si.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//0x0100007f;
int nRet = bind(sockServer, (sockaddr*)&si, sizeof(si));
if (nRet == SOCKET_ERROR)
{
cout << "bind 失败" << endl;
return 0;
}

for (int i = 0; i < 0x100000; ++i)
{
int nVal = 0;
sockaddr_in siFrom = {};
int nSizeofSi = sizeof(sockaddr_in);
recvfrom(sockServer, (char*)&nVal, sizeof(nVal), 0, (sockaddr*)&siFrom, &nSizeofSi);
printf("val:%08X \r\n", nVal);
}

system("pause");
cout << "Hello World!\n";
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// Client.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <iostream>
using namespace std;
#define WIN32_LEAN_AND_MEAN//仅保留windows.h中的必要的头文件
//如果不加这一行则要把Winsock2.h放到windows.h前面,否则会因重定义而报错
#include <windows.h>
#include <Winsock2.h>
#pragma comment(lib,"Ws2_32.lib")

int main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{
return 0;
}

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

SOCKET sockClient = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sockClient == INVALID_SOCKET)
{
cout << "socket 失败" << endl;
return 0;
}
sockaddr_in si;
si.sin_family = AF_INET;
si.sin_port = htons(0x7788);//h-host to n-network s-short ntohs
si.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//0x0100007f;

for (int i = 0; i < 0x100000; ++i)
{
sendto(sockClient, (char*)&i, sizeof(i), 0, (sockaddr*)&si, sizeof(si));
}

system("pause");
cout << "Hello World!\n";
}

image-20240719221629116

udp可能丢包,还可能出现先发出的包比后发的包晚收到

tcp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// Server.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <iostream>
using namespace std;
#define WIN32_LEAN_AND_MEAN//仅保留windows.h中的必要的头文件
//如果不加这一行则要把Winsock2.h放到windows.h前面,否则会因重定义而报错
#include <windows.h>
#include <Winsock2.h>
#pragma comment(lib,"Ws2_32.lib")
DWORD WINAPI WorkThreadFunc(LPVOID lpParam);
int main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{
return 0;
}

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

SOCKET sockServer = socket(AF_INET, SOCK_STREAM , IPPROTO_TCP);
if (sockServer == INVALID_SOCKET)
{
cout << "socket 失败" << endl;
return 0;
}
//127.0.0.1-回环地址
sockaddr_in si;
si.sin_family = AF_INET;
si.sin_port = htons(0x7788);
si.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//0x0100007f;
int nRet = bind(sockServer, (sockaddr*)&si, sizeof(si));
if (nRet == SOCKET_ERROR)
{
cout << "bind 失败" << endl;
return 0;
}

nRet = listen(sockServer, 1);
if (nRet == SOCKET_ERROR)
{
cout << "listen 失败" << endl;
return 0;
}

sockaddr_in siClient;
int nLen = sizeof(siClient);
SOCKET sock = accept(sockServer, (sockaddr*)&siClient, &nLen);
if (sock == INVALID_SOCKET)
{
cout << "accept 失败" << endl;
}

for (int i = 0; i < 0x100000; ++i)
{
int nVal = 0;
sockaddr_in siFrom = {};
int nSizeofSi = sizeof(sockaddr_in);
recv(sock, (char*)&nVal, sizeof(nVal), 0);
printf("i:%d val:%08X \r\n", i, nVal);
}

system("pause");
cout << "Hello World!\n";
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// Client.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <iostream>
using namespace std;
#define WIN32_LEAN_AND_MEAN//仅保留windows.h中的必要的头文件
//如果不加这一行则要把Winsock2.h放到windows.h前面,否则会因重定义而报错
#include <windows.h>
#include <Winsock2.h>
#pragma comment(lib,"Ws2_32.lib")

int main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{
return 0;
}

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

SOCKET sockClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sockClient == INVALID_SOCKET)
{
cout << "socket 失败" << endl;
return 0;
}
sockaddr_in si;
si.sin_family = AF_INET;
si.sin_port = htons(0x7788);
si.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//0x0100007f;
int nRet = connect(sockClient, (sockaddr*)&si, sizeof(si));
if (nRet == SOCKET_ERROR)
{
cout << "connect 失败" << endl;
return 0;
}

for (int i = 0; i < 0x100000; ++i)
{
send(sockClient, (char*)&i, sizeof(i), 0);
}

system("pause");
cout << "Hello World!\n";
}

image-20240719223437679

tcp不会丢包,而且会按顺序接受到包