使用visual studio完成h264文件的TCP协议传输,给出发送和接收的代码,发送端打印传输的文件的大小,接收端要打印每一帧是否接收正确,还要计算传输时延
时间: 2024-06-08 12:10:40 浏览: 15
以下是发送端的代码示例:
```c++
#include <iostream>
#include <fstream>
#include <WinSock2.h>
#include <WS2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
int main()
{
// 初始化 Winsock
WSADATA wsaData;
int result = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (result != 0)
{
cout << "WSAStartup failed with error: " << result << endl;
return 1;
}
// 创建套接字
SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET)
{
cout << "socket failed with error: " << WSAGetLastError() << endl;
WSACleanup();
return 1;
}
// 设置服务器地址和端口号
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(12345);
inet_pton(AF_INET, "127.0.0.1", &serverAddr.sin_addr);
// 连接服务器
result = connect(sock, (sockaddr*)&serverAddr, sizeof(serverAddr));
if (result == SOCKET_ERROR)
{
cout << "connect failed with error: " << WSAGetLastError() << endl;
closesocket(sock);
WSACleanup();
return 1;
}
// 打开 H264 文件
ifstream h264File("test.h264", ios::binary | ios::ate);
if (!h264File.is_open())
{
cout << "Failed to open H264 file." << endl;
closesocket(sock);
WSACleanup();
return 1;
}
// 获取 H264 文件大小
int fileSize = (int)h264File.tellg();
cout << "H264 file size: " << fileSize << " bytes." << endl;
// 将文件指针移到文件头
h264File.seekg(0, ios::beg);
// 发送 H264 文件
char buffer[1024];
int bytesSent = 0;
while (bytesSent < fileSize)
{
int bytesToRead = min((int)sizeof(buffer), fileSize - bytesSent);
h264File.read(buffer, bytesToRead);
result = send(sock, buffer, bytesToRead, 0);
if (result == SOCKET_ERROR)
{
cout << "send failed with error: " << WSAGetLastError() << endl;
closesocket(sock);
WSACleanup();
return 1;
}
bytesSent += result;
}
// 关闭文件和套接字
h264File.close();
closesocket(sock);
WSACleanup();
return 0;
}
```
以下是接收端的代码示例:
```c++
#include <iostream>
#include <fstream>
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <chrono>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
int main()
{
// 初始化 Winsock
WSADATA wsaData;
int result = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (result != 0)
{
cout << "WSAStartup failed with error: " << result << endl;
return 1;
}
// 创建套接字
SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET)
{
cout << "socket failed with error: " << WSAGetLastError() << endl;
WSACleanup();
return 1;
}
// 绑定套接字到本地端口号
sockaddr_in localAddr;
localAddr.sin_family = AF_INET;
localAddr.sin_port = htons(12345);
localAddr.sin_addr.s_addr = INADDR_ANY;
result = bind(sock, (sockaddr*)&localAddr, sizeof(localAddr));
if (result == SOCKET_ERROR)
{
cout << "bind failed with error: " << WSAGetLastError() << endl;
closesocket(sock);
WSACleanup();
return 1;
}
// 监听套接字
result = listen(sock, SOMAXCONN);
if (result == SOCKET_ERROR)
{
cout << "listen failed with error: " << WSAGetLastError() << endl;
closesocket(sock);
WSACleanup();
return 1;
}
// 接受连接请求
SOCKET clientSock = accept(sock, NULL, NULL);
if (clientSock == INVALID_SOCKET)
{
cout << "accept failed with error: " << WSAGetLastError() << endl;
closesocket(sock);
WSACleanup();
return 1;
}
// 创建 H264 文件
ofstream h264File("received.h264", ios::binary);
if (!h264File.is_open())
{
cout << "Failed to create H264 file." << endl;
closesocket(clientSock);
closesocket(sock);
WSACleanup();
return 1;
}
// 接收 H264 文件
char buffer[1024];
int bytesReceived = 0;
int totalBytesReceived = 0;
int fileSize = 0;
auto start = chrono::high_resolution_clock::now();
while (true)
{
result = recv(clientSock, buffer, sizeof(buffer), 0);
if (result == SOCKET_ERROR)
{
cout << "recv failed with error: " << WSAGetLastError() << endl;
break;
}
else if (result == 0) // 连接断开
{
break;
}
else
{
bytesReceived += result;
totalBytesReceived += result;
h264File.write(buffer, result);
if (fileSize == 0 && totalBytesReceived >= 4) // 前四个字节是文件大小
{
fileSize = *(int*)buffer;
cout << "H264 file size: " << fileSize << " bytes." << endl;
}
if (bytesReceived >= 1024 * 1024) // 每接收 1MB 打印一次进度
{
cout << "Received " << totalBytesReceived << " bytes." << endl;
bytesReceived = 0;
}
memset(buffer, 0, sizeof(buffer));
}
}
auto end = chrono::high_resolution_clock::now();
auto duration = chrono::duration_cast<chrono::milliseconds>(end - start).count();
cout << "Received " << totalBytesReceived << " bytes in " << duration << " milliseconds." << endl;
// 关闭文件和套接字
h264File.close();
closesocket(clientSock);
closesocket(sock);
WSACleanup();
return 0;
}
```