网络编程 UDP 聊天功能

UDP(User  Datagram Protocol),用户数据包协议。

在选择使用协议的时候,选择UDP必须要谨慎。在网络质量令人十分不满意的环境下,UDP协议数据包丢失会比较严重。但是由于UDP的特性:它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。比如我们聊天用的QQ就是使用的UDP协议。

服务器端程序:

#include <WinSock2.h>
#include <stdio.h>
#include <iostream>

using namespace std;

int main()
{
	//加载套接字库,1.1版本
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;

	wVersionRequested = MAKEWORD( 1, 1 );

	err = WSAStartup( wVersionRequested, &wsaData );
	if ( err != 0 ) 
	{
		return 0;
	}


	if ( LOBYTE( wsaData.wVersion ) != 1 ||
		HIBYTE( wsaData.wVersion ) != 1 ) 
	{
		WSACleanup( );
		return 0; 
	}
	//创建套接字
	SOCKET sockSrv = socket(AF_INET,SOCK_DGRAM,0);

	//将套接字绑定到一个本地地址和端口上
	SOCKADDR_IN AddrSrv;
	AddrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	AddrSrv.sin_family = AF_INET;
	AddrSrv.sin_port = htons(6000);

	bind(sockSrv,(SOCKADDR *)&AddrSrv,sizeof(AddrSrv));
	
	//接收和发送
	char recvBuf[100];
	char sendBuf[100];
	char tempBuf[200];
	SOCKADDR_IN AddrClient;//存储发送端的地址信息
	int len = sizeof(AddrClient);

	while(1)
	{
		recvfrom(sockSrv,recvBuf,strlen(recvBuf),0,(SOCKADDR*)&AddrClient,&len);
		if ('q' == recvBuf[0])
		{
			sendto(sockSrv,"q",strlen("q")+1,0,(SOCKADDR*)&AddrClient,len);
			cout << "end chat";
			break;
		}
		sprintf_s(tempBuf,"%s say : %s\n",inet_ntoa(AddrClient.sin_addr),recvBuf);
		cout << tempBuf;
		
		cout << "你要发送的数据:";
		gets(sendBuf);
		sendto(sockSrv,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&AddrClient,len);
	}
	

	closesocket(sockSrv);
	WSACleanup();

}

客户端程序:

#include <WinSock2.h>
#include <stdio.h>
#include <iostream>

using namespace std;

int main()
{
	//加载套接字库,1.1版本
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;

	wVersionRequested = MAKEWORD( 1, 1 );

	err = WSAStartup( wVersionRequested, &wsaData );
	if ( err != 0 ) 
	{
		return 0;
	}


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

	//创建套接字
	SOCKET sockClient = socket(AF_INET,SOCK_DGRAM,0);

	//存放要发送到的机器的地址信息
	SOCKADDR_IN addr;
	addr.sin_addr.S_un.S_addr = inet_addr("59.73.163.254");//要发送的机器的IP
	addr.sin_family = AF_INET;
	addr.sin_port = htons(6000);//要发送到的机器的端口

	//接收和发送
	char recvBuf[100];
	char sendBuf[100];
	char tempBuf[200];

	int len = sizeof(SOCKADDR);

	while(1)
	{
		cout << "输入要发送的数据:";
		gets(sendBuf);
		
		sendto(sockClient,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&addr,sizeof(addr));

		//用addr接收返回的地址结构
		recvfrom(sockClient,recvBuf,strlen(recvBuf),0,(SOCKADDR*)&addr,&len);
		if ('q' == recvBuf[0])
		{
			sendto(sockClient,"q",strlen("q")+1,0,(SOCKADDR*)&addr,len);
			cout << "end chat";
			break;
		}

		sprintf_s(tempBuf,"%s say :%s\n",inet_ntoa(addr.sin_addr),recvBuf);
		cout << tempBuf;

	}


	closesocket(sockClient);
	WSACleanup();
}


UDP编程流程:


另附,一个结构体的说明,和网络字节序的转换。和怎么将一个字符串转成一个点分十进制的IP形式等



不要忘记加入ws2_32.lib库


note:别忘记附加ws2_32.lib库。然后再建立套接字和绑定时,可以写if语句判断一下,创建套接字、绑定是否成功等。WSAGetLastError()函数可以输出错误码。可以到VS--工具--错误查找中,输入该错误码查找错误!



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值