WindowsSocket編程初步-UDP

        學期期末C語言實訓,其中有個項目叫“UDP文件傳輸系統”。

        其實如果只學了C語言,感覺做這些東西是根本不現實的。現在明白了,我們這一個學期就只是單純學習語言,其中的基本語法。實際上根本談不上寫出實際的程序。

當時記得自己用兩個循環,打出了9*9乘法口訣表時,那叫一個開心啊,感覺這就是編程了。(天真爛漫啊!)


        然後繼續說這個udp, 我覺得,其中涉及到的知識:

1. 網絡原理(非常基礎的部分):比如說基本的,數據走了哪幾層,封裝、解封裝,c/s模式。。。等等的,就是一般網絡原理書第一章的簡介和概要,這些知識應該要知道。

2. Windows API 的基本知識, 這個好像在網絡原理也講了,套接字(Socket)的概念一定要有。

3. 基本的C語言語法基礎一定要有。


其他的改天再寫,先發一點最基本的代碼:


服務端


#include <stdio.h>
#include <string.h>
#include <WINSOCK2.H>
#pragma comment(lib, "ws2_32.lib")

struct receive
{
	int length;
	char ip[100];           // 用於接收對方ip地址
	char received_Buf[255]; // 用於接收對方主機名
} RECEIVE_message;

int main(int argc, const char* argv[])
{
	WSAData wsaData;
	int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (iResult != 0)
	{
		printf("WSAStartup failed: %d\n", iResult);
		return -1;
	}

	// 創建套接字
	SOCKET Socket_of_Server;

	Socket_of_Server = socket(AF_INET, SOCK_DGRAM, 0);
	if (Socket_of_Server == INVALID_SOCKET)
	{
		printf("Build socket filed: %d\n", WSAGetLastError());
		WSACleanup();
		return -1;
	}

	// 綁定套接字地址
	sockaddr_in LocalAddres;
	LocalAddres.sin_family = AF_INET;
	LocalAddres.sin_addr.s_addr = htonl(INADDR_ANY);
	LocalAddres.sin_port = htons(20000);  // 注意此處使用網絡模式的 端口號

	iResult = bind(Socket_of_Server, (SOCKADDR*)&LocalAddres, sizeof(SOCKADDR_IN));
	if (0 != iResult)
	{
		WSACleanup();
		return -1;
	}
	sockaddr_in RemoteAddres;						// &RemoteAddres是緩衝區地址,保存客戶端的IP和端口等信息
	int RemoteAddres_length = sizeof(RemoteAddres); // RemoteAddres_length是包含地址信息的長度

	printf("服務端正在運行:\n");
	printf("********************************************************************************\n");
	
	// 等待客戶端數據
	while(1)
	{	
		// 接收客戶端的數據(包含對方主機名、IP地址)
		recvfrom(Socket_of_Server, 
			(char*) &RECEIVE_message.received_Buf, sizeof(RECEIVE_message.received_Buf), 0, 
			(sockaddr*)&RemoteAddres, &RemoteAddres_length);
		printf("對方主機說:%s\n", RECEIVE_message.received_Buf);

		char words[1000];
		printf("Server:");
		gets(words);
		sendto(Socket_of_Server, words, strlen(words) + 1, 0, (sockaddr*)&RemoteAddres, sizeof(RemoteAddres));
	}
	
	// 關閉套接字
    closesocket(Socket_of_Server);
	// 清除動態鏈接
    WSACleanup();
	
    return 0;
}
客戶端
 
// 客戶端
#include <stdio.h>
#include <string.h>
#include <WINSOCK2.H>
#include <windows.h>
#pragma comment(lib, "ws2_32.lib")

int main(int argc, const char* argv[])
{
	WSAData wsaData;
	// 初始化套接字
	int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (iResult != 0)
	{
		printf("WSAStartup faiied :%d\n", iResult);
		return -1;
	}
	
	// 創建套接字
	SOCKET socket_of_Client;
	socket_of_Client = socket(AF_INET, SOCK_DGRAM, 0);
	if (socket_of_Client == INVALID_SOCKET)
	{
		printf("Build socket filed: %d\n", WSAGetLastError());
		WSACleanup();
		return -1;
	}

	// 定義遠端套接字
	char Server_ip[] = "127.0.0.1";
	unsigned short Server_port = 20000;
	/* 
		注意, 此處是在調試過程中使用的IP和端口號
		真實網絡中應該由服務器直接獲取,或者由用戶手動輸入服務器IP
	*/

	// 指明對方服務器的地址結構
	sockaddr_in Server_Address;
	Server_Address.sin_family = AF_INET;
	Server_Address.sin_addr.s_addr = inet_addr(Server_ip);
	Server_Address.sin_port = htons(Server_port);

	int Server_Address_length = sizeof(Server_Address);

	// 與服務端通信
	printf("客戶端正在運行:\n");
	printf("********************************************************************************\n");
	while (1)
	{
		char words[1000];
		printf("Client:");

		gets(words);
		sendto(socket_of_Client, words, strlen(words) + 1, 0, (sockaddr*)&Server_Address, sizeof(Server_Address));

		recvfrom(socket_of_Client, (char*) &words, sizeof(words), 0, 
				 (sockaddr*)&Server_Address, &Server_Address_length);
		printf("Server:");
		puts(words);
	}

	WSACleanup();
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章