UDP通信

客户端:

// UDP_Client.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <winsock2.h>  
#include <windows.h>  
#include <stdio.h>  

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

int main() 
{  

	/*****************************************/
	/****(1)初始化WSA***********************/
	/*****************************************/	
	
	WSADATA data;  
	/*MAKEWORD(bLow,bHigh)  将bLow与bHigh两个字节合并成一个word型,bLow 在低位,bHigh在高位 */
	WORD wVersionRequested = MAKEWORD(2, 0);  
	
	/*WSAStartup(WORD,LPWSADATA)  
		WORD指明程序请求使用的Socket版本,其中高位字节指明副版本、低位字节指明主版本
		LPWSADATA 操作系统利用第二个参数LPWSADATA返回请求的Socket的版本信息
	*/		
	WSAStartup(wVersionRequested, &data);  

	/*****************************************/
	/****(2)创建套接字(socket)************/
	/*****************************************/
			 /*socket( domain,       type,protocol);
			 domain:协议域,又称协议族(family)   AF_INET决定了要用ipv4地址(32位的)与端口号(16位的)的组合
			 type:指定Socket类型	数据报式Socket(SOCK_DGRAM)是一种无连接的Socket,对应于无连接的UDP服务应用
			 protocol:指定协议	IPPROTO_UDP对应UDP传输协议
			 */	
	SOCKET s = socket(AF_INET, SOCK_DGRAM, 0);  


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

	/*****************************************/
	/****(3)连接到服务器********************/
	/*****************************************/
	sockaddr_in addrServer;  
	int nSockAddrSize = sizeof(addrServer);

	
	sockaddr_in addr;
	addr.sin_family = AF_INET;  /*Address family一般来说AF_INET(地址族)PF_INET(协议族)*/  
	addr.sin_port = htons(75);  /*Port number(必须要采用网络数据格式,普通数字可以用htons()函数转换成网络数据格式的数字)*/  
	addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");  // 设置套接字的主机IP地址为 127.0.0.1
	                          //inet_addr() 根据点十进制格式表示的IP地址返回一个适合分配给S_addr的u_long型数值


	/*****************************************/
	/****(4)发送和接受数据******************/
	/*****************************************/	
	
	//发送
	
	/*sendto(	s,	buf,	len,	flags,	to,	tolen)
	s:	(可能已建立连接)套接字描述符
	buf:指向缓冲区的指针,该缓冲区包含将要发送的数据
	len:指定缓冲区中数据的长度
	flags:设定的值影响函数调用的行为,一般设置为0即可
	to:可选指针,指定目标套接字的地址
	tolen:目标套接字的地址的长度
	*/
	/*
	recvfrom(	s,	buf,	len,	flags,	from,	fromlen)
	s:准备接受数据的套接字
	buf:指向缓冲区的指针
	len:缓冲区的长度
	flags:设定的值将影响函数的行为,一般设置为0即可
	from:指向地址结构体的指针,用于接受发送数据方的地址信息
	fromlen:整型指针,in/out类型参数,
	*/
	
	static const char szSendToServer[] = "Hello! I'm trying to connect you!";  
	char szBuff[50] = { 0 };  	
	
	  sendto(s, szSendToServer, sizeof(szSendToServer), 0, (sockaddr*)&addr      ,  nSockAddrSize);  
	recvfrom(s,         szBuff,         sizeof(szBuff), 0, (sockaddr*)&addrServer, &nSockAddrSize);  
	  printf("%s\n", szBuff);  

	/*****************************************/
	/****(5)关闭套接字(断开连接)**********/
	/*****************************************/
	closesocket(s);  
	WSACleanup();  
	
	/*之后如果还有输入(鼠标/键盘),退出程序*/
	if (getchar()) return 0;  
	return 0;  
}  

服务端:

// UDP_Server.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <winsock2.h>  
#include <windows.h>  
#include <stdio.h>  

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

int main() 
{  

 	/*****************************************/
	/****(1)初始化WSA***********************/
	/*****************************************/ 

	WSADATA data;  
	/*MAKEWORD(bLow,bHigh)  将bLow与bHigh两个字节合并成一个word型,bLow 在低位,bHigh在高位 */
	WORD wVersionRequired = MAKEWORD(2, 0);//wVersionRequired为值为2的无符号短word型,低位为2,高位为0
	
	/*WSAStartup(WORD,LPWSADATA)  
		WORD指明程序请求使用的Socket版本,其中高位字节指明副版本、低位字节指明主版本
		LPWSADATA 操作系统利用第二个参数LPWSADATA返回请求的Socket的版本信息
	*/	
	WSAStartup(wVersionRequired, &data);  
	//
	
	/*****************************************/
	/****(2)创建套接字(socket)************/
	/*****************************************/
			 /*socket(     af,       type,protocol);
			 af:指定地址族    
			 type:指定Socket类型	数据报式Socket(SOCK_DGRAM)是一种无连接的Socket,对应于无连接的UDP服务应用
			 protocol:指定协议	IPPROTO_UDP对应UDP传输协议
			 */
	SOCKET s = socket(AF_INET, SOCK_DGRAM, 0);  
			 /*socket(AF_INET, SOCK_DGRAM, 0);
			    AF_INET:对于TCP/IP协议的套接字,只能是 AF_INET
			 SOCK_DGRAM:SOCK_DGRAM产生数据报套接字
			          0:系统根据地址格式与套接字类别,自动选择一个合适的协议
			 */
	
	
	
	
	
	
	
	/*****************************************/
	/*(3)将套接字绑定到一个本地地址与端口上*/
	/*****************************************/
	
	sockaddr_in addr;  
	addr.sin_family = AF_INET;  /*指定地址家族 对于TCP/IP协议的套接字,必须设置为AF_INET */
	addr.sin_port = htons(75);  /*指定将要分配给套接字的端口(必须要采用网络数据格式,普通数字可以用htons()函数转换成网络数据格式的数字)*/
	addr.sin_addr.S_un.S_addr = INADDR_ANY;  //套接字的主机IP地址   
	    //INADDR_ANY允许套接字向任何分配给本机的IP地址发送或接受数据,允许一个独立应用接受发自多个接口的回应
	
	/*bind(s,name,namelen)  此函数将本地地址与套接字关联
	s:一个未绑定套接字描述符的识别符
	name:分配给sockaddr结构中套接字的地址
	namelen:name参数中数值的长度
	*/
	bind(s, (sockaddr*)&addr, sizeof(addr));  

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

	sockaddr_in addrClient;  //客户端的地址
	int nSockAddrSize = sizeof(addrClient);

	/*sendto(	s,	buf,	len,	flags,	to,	tolen)
	s:	(可能已建立连接)套接字描述符
	buf:指向缓冲区的指针,该缓冲区包含将要发送的数据
	len:指定缓冲区中数据的长度
	flags:设定的值影响函数调用的行为,一般设置为0即可
	to:可选指针,指定目标套接字的地址
	tolen:目标套接字的地址的长度
	*/
	/*
	recvfrom(	s,	buf,	len,	flags,	from,	fromlen)
	s:准备接受数据的套接字
	buf:指向缓冲区的指针
	len:缓冲区的长度
	flags:设定的值将影响函数的行为,一般设置为0即可
	from:指向地址结构体的指针,用于接受发送数据方的地址信息
	fromlen:整型指针,in/out类型参数,
	*/

	/*****************************************/
	/*(4)检测是否收到客户端发出的数据,如果接收到就显示接收到的数据,并向客户端发送一个数据进行交互*/
	/*****************************************/
	
	static const char szAnswerClient[] = "Hello! You've been connected!";  
	char szBuff[50] = { 0 };	
	
	if (recvfrom(s, szBuff, sizeof(szBuff), 0, (sockaddr*)&addrClient, &nSockAddrSize) > 0)
		          //szBuff[50] = { 0 }; 
	//如果接收到来自客户端的信息  
	{  
		printf("There is one client(%s) connected!\n", inet_ntoa(addrClient.sin_addr));
                //inet_ntoa() 接受一个in_addr结构体参数,返回一个以点分十进制格式表示的IP地址字符串		
		printf("%s\n", szBuff);//显示接收到的数据  
		sendto(s, szAnswerClient, sizeof(szAnswerClient), 0, (sockaddr*)&addrClient, nSockAddrSize); 
		        //向客户端发送"Hello! You've been connected!"以表示连接成功
	            //szAnswerClient[] = "Hello! You've been connected!";
	}  

	/*****************************************/
	/****(5)关闭套接字(断开连接)**********/
	/*****************************************/
	
	closesocket(s);  
	WSACleanup();  

	/*之后如果还有输入(鼠标/键盘),退出程序*/	
	if (getchar()) return 0;  
	return 0;  
}  





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值