天天看点

【网络编程】UDP数据传输及文件传输实验实验要求:源码

实验要求:

内容1:利用数据报套接字实现数据传输

1.    客户端创建UDP套接字,向指定的服务端发送数据;

2.    服务端接收到新数据,显示是谁发送过来的,并把该数据回传给发送方;

3.    服务端使用多线程来实现并发。

4.    观察在服务端启动和不启动时,客户端的运行情况。

内容2:使用UDP套接字实现文件传输

1.    客户端向服务端发送文件名

2.    客户端向服务端传输文件内容;

3.    双方关闭套接字。

4.    注意收发速度对文件传输结果的影响。

源码

客户端

#include "stdafx.h" 
#include <iostream>
#include <stdio.h>  
#include <winsock2.h>  
#include <windows.h>
using namespace std;
#pragma comment(lib, "ws2_32.lib")   
const int MAX_IP_PATH = 15;
const int  MAX_BUFFER = 10240;
const int NAME = 10240;

int main(int argc, char* argv[])
{
	WORD socketVersion = MAKEWORD(2, 2);
	WSADATA wsaData;
	if (WSAStartup(socketVersion, &wsaData) != 0)
	{
		return 0;
	}
	SOCKET ClientSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (ClientSocket == INVALID_SOCKET)
	{
		cout << "Create Socket Failed::" << GetLastError() << endl;
		WSACleanup();
		return -1;
	}

	char IP_ADDRESS[MAX_IP_PATH];
	unsigned int PORT;
	cout << "connect IP:";
	cin >> IP_ADDRESS;
	cout << endl;
	cout << "connect port:";
	cin >> PORT;
	cout << endl;

	sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(PORT);
	sin.sin_addr.S_un.S_addr = inet_addr(IP_ADDRESS);

//消息发送回传
	unsigned int msglen;
	char SendBuffer[MAX_BUFFER];
	int len = sizeof(sin);
	cout << "input message:";
	cin >> SendBuffer;
	cout << endl;
	msglen = strlen(SendBuffer);
	sendto(ClientSocket, SendBuffer, strlen(SendBuffer), 0, (sockaddr *)&sin, len);

	int Ret;
	char RecvBuffer[MAX_BUFFER];
	Ret = recvfrom(ClientSocket, RecvBuffer, msglen, 0, (sockaddr *)&sin, &len);
	if (Ret <0)
	{
		cout << "receive error:" << WSAGetLastError();
		closesocket(ClientSocket);
		WSACleanup();
		return -1;
	}
	RecvBuffer[Ret] = 0;
	cout << "receive message: " << RecvBuffer << endl;

	unsigned int ThreadPORT;
	Ret = recvfrom(ClientSocket, (char *)&ThreadPORT, msglen, 0, (sockaddr *)&sin, &len);
	if (Ret <0)
	{
		cout << "receive post error " << WSAGetLastError();
		system("pause");
		return -1;
	}
	cout << "receive post:" <<ThreadPORT << endl;
	sin.sin_port = htons(ThreadPORT);
//文件传输
	char filename[NAME];
	cout << "file name:\n";
	cin >> filename;
	sendto(ClientSocket, filename, strlen(filename), 0, (sockaddr *)&sin, len);


	FILE *fp = fopen(filename, "rb");
	if (fp == NULL)
	{
		printf("create file failed\n");
		system("pause");
		return -1;
	}
	fseek(fp, 0L, SEEK_END);
	unsigned int size = ftell(fp);  
	cout << "file size:" << size << endl;
	fseek(fp, 0, SEEK_SET);
	sendto(ClientSocket, (char *)&size, 4, 0, (sockaddr *)&sin, len);

	int cnt = 1;
	unsigned int Length;
	cout << "begin to send file...." << endl;
	while (size > 0)
	{
		memset(SendBuffer, 0, sizeof(char));
		if (size >= MAX_BUFFER)
		{
			Length = fread(SendBuffer, sizeof(char), MAX_BUFFER, fp);
			size-= MAX_BUFFER;
		}
		else
		{
			Length = fread(SendBuffer, sizeof(char), Length, fp);
			size=0;
		}
		sendto(ClientSocket, SendBuffer, (int)Length, 0, (sockaddr *)&sin, len);
		cout << "pack " << cnt++ << ", file " << size << endl;
	}

	closesocket(ClientSocket);
	cout << "send file ok" << endl;;
	system("pause");
	WSACleanup();
	return 0;
}
           

服务端

#include "stdafx.h" 
#include <iostream>
#include <cstdio>  
#include <winsock2.h> 
#include <windows.h>

using namespace std;
#pragma comment(lib, "ws2_32.lib")   
const unsigned int POST = 8000;
const int MAX_BUFFER = 10240;
const int NAME = 10240;


DWORD WINAPI ClientThread(LPVOID lpParameter)
{
	SOCKET ClientSocket = (SOCKET)lpParameter;
	sockaddr_in remoteAddr;
	int nAddrLen = sizeof(remoteAddr);
	int Ret = 0;

	char name[NAME];
	Ret = recvfrom(ClientSocket, name, MAX_BUFFER, 0, (sockaddr *)&remoteAddr, &nAddrLen);
	if (Ret <= 0)
	{
		cout << "Receive Error£¡" << WSAGetLastError();
		return -1;
	}
	name[Ret] = 0;
	printf("Receive FileName From Client :: %s\n", name);

	unsigned int length;
	recvfrom(ClientSocket, (char*)&length, 4, 0, (sockaddr *)&remoteAddr, &nAddrLen);
	cout << "flie length :" << length << endl;

	FILE *fp = NULL;
	fp = fopen(name, "ab");
	if (fp == NULL)
	{
		printf("Open File Error£¡\n");
		return -1;
	}
	cout << "begin to get file...." << endl;
	int cnt = 0;
	char RecvBuffer[MAX_BUFFER];
	while (length>0)
	{
		memset(RecvBuffer, 0, sizeof(RecvBuffer));
		Ret = recvfrom(ClientSocket, RecvBuffer, MAX_BUFFER, 0, (sockaddr *)&remoteAddr, &nAddrLen);
		if (Ret <= 0)
		{
			cout << "receive error " << WSAGetLastError() << endl;;
			closesocket(ClientSocket);
			fclose(fp);
			return -1;
		}
		fwrite(RecvBuffer, sizeof(char), Ret, fp);
		fflush(fp);
		length -= Ret;
		cout << "pack " << ++cnt << "file " << length << endl;
	}
	cout << "get file" << endl;
	closesocket(ClientSocket);
	fclose(fp);
}

int main(int argc, char* argv[])
{
	WORD sockVersion = MAKEWORD(2, 2);
	WSADATA wsaData;
	if (WSAStartup(sockVersion, &wsaData) != 0)
	{
		return 0;
	}

	SOCKET serSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (serSocket == INVALID_SOCKET)
	{
		printf("socket error !");
		WSACleanup();
		return 0;
	}

	sockaddr_in serAddr;
	serAddr.sin_family = AF_INET;
	serAddr.sin_port = htons(POST);
	serAddr.sin_addr.S_un.S_addr = INADDR_ANY;
	if (bind(serSocket, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR)
	{
		printf("bind error !");
		closesocket(serSocket);
		WSACleanup();
		return 0;
	}

	cout << "listening the client" << endl;

	sockaddr_in remoteAddr;
	int nAddrLen = sizeof(remoteAddr);
	int cnt = 0;
	char RecvBuffer[MAX_BUFFER];
	while (true)
	{
		memset(RecvBuffer, 0, sizeof(RecvBuffer));
		int Ret = recvfrom(serSocket, RecvBuffer, MAX_BUFFER, 0, (sockaddr *)&remoteAddr, &nAddrLen);
		if (Ret < 0)
		{
			cout << "receive error " << WSAGetLastError();
			continue;
		}
		RecvBuffer[Ret] = 0x00;
		cout << "client " << ++cnt << ": " << inet_ntoa(remoteAddr.sin_addr) << endl;
		printf("say:%s\n", RecvBuffer);

		sendto(serSocket, RecvBuffer, strlen(RecvBuffer), 0, (sockaddr *)&remoteAddr, nAddrLen);
		SOCKET ClientSocket;
		ClientSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
		if (ClientSocket == INVALID_SOCKET)
		{
			printf("socket error !");
			WSACleanup();
			continue;
		}

		sockaddr_in ClientAddr;
		unsigned int ThreadPORT = POST;
		while (ThreadPORT <= 65535)
		{
			++ThreadPORT;
			ClientAddr.sin_family = AF_INET;
			ClientAddr.sin_port = htons(ThreadPORT);
			ClientAddr.sin_addr.S_un.S_addr = INADDR_ANY;
			if (bind(ClientSocket, (sockaddr *)&ClientAddr, sizeof(ClientAddr)) != SOCKET_ERROR)
				break;
		}
		if (ThreadPORT > 65535)
		{
			cout << "creat thread failed" << endl;
			continue;
		}
		cout << "the post " << ThreadPORT << " to client  " << cnt << endl;
		sendto(serSocket, (const char*)&ThreadPORT, sizeof(unsigned int), 0, (sockaddr *)&remoteAddr, nAddrLen);

		HANDLE hThread = CreateThread(NULL, 0, ClientThread, (LPVOID)ClientSocket, 0, NULL);
		if (hThread == NULL)
		{
			cout << "Create Thread Failed!" << endl;
			continue;
		}
		CloseHandle(hThread);
	}
	closesocket(serSocket);
	WSACleanup();
	return 0;
}