Windows Socket UDP协议(服务器与客户端)

Windows Socket UDP协议(服务器与客户端)

这是一个经常用到的老掉牙的主题了,为了以后用到方便,所以稍微注释了一下然后放上来,代码是本人修改过的,所以也就选成了“原创”。其实现在做码农的,又有多少基础模块能说大体的代码都是自己搞出来的呢?这个“原创”的界定很难!好了,废话不多说,贴代码,基本上用VS的拷过去也是能直接运行的。

服务器普通实现代码

<span style="color:#3366ff;">#include <stdio.h> 
#include <Winsock2.h> 

#pragma comment(lib,"Ws2_32.lib")//连接Sockets相关库

void main()
{
	SOCKET socket1;
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2, 1), &wsaData)) //初始化
	{
		printf("Winsock无法初始化!\n");
		WSACleanup();
		return;
	}
	printf("服务器开始创建SOCKET。\n");
	struct sockaddr_in local;//本机地址相关结构体
	struct sockaddr_in from;//客户端地址相关结构体
	int fromlen = sizeof(from);
	local.sin_family = AF_INET;
	local.sin_port = htons(27015); ///监听端口 
	local.sin_addr.s_addr = INADDR_ANY; ///本机 
	socket1 = socket(AF_INET, SOCK_DGRAM, 0);
	bind(socket1, (struct sockaddr*)&local, sizeof(local));//绑定SOCKET,此步关键
	char buffer[1024] = "\0";
	if (recvfrom(socket1, buffer, sizeof(buffer), 0, (struct sockaddr*)&from, &fromlen) != SOCKET_ERROR)//阻塞接受客户端的请求
	{
		printf("连接成功,开始发送数据\n");
	}
	while (1)
	{
		sendto(socket1, buffer, sizeof(buffer), 0, (struct sockaddr*)&from, fromlen);//发数据给客户端,由于是
		Sleep(200);
	}
	closesocket(socket1);
	WSACleanup();
}</span>


客户端普通实现代码

#include <stdio.h> 
#include <Winsock2.h> 

#pragma comment(lib,"Ws2_32.lib")//连接Sockets相关库

void main()
{
	SOCKET socket1;
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2, 1), &wsaData)) //初始化
	{
		printf("Winsock无法初始化!\n");
		WSACleanup();
		return;
	}
	printf("客户端开始创建SOCKET。\n");
	struct sockaddr_in server;
	int len = sizeof(server);
	server.sin_family = AF_INET;
	server.sin_port = htons(27015); ///server的监听端口 
	server.sin_addr.s_addr = inet_addr("127.0.0.1"); ///server的地址 
	socket1 = socket(AF_INET, SOCK_DGRAM, 0);
	char buffer[1024] = "haha\0";
	if (sendto(socket1, buffer, sizeof(buffer), 0, (struct sockaddr*)&server, len) != SOCKET_ERROR)//发送信息给服务器,发送完进入等待,代表服务器在客户端启动前必须是等待状态
	{
		printf("发送请求,等待客户端接受并发送数据\n");
	}
	while (1)
	{
		Sleep(100);
		if (recvfrom(socket1, buffer, sizeof(buffer), 0, (struct sockaddr*)&server, &len) != SOCKET_ERROR)
		printf("从客户端接收到的数据:%s\n", buffer);
	}
	closesocket(socket1);
	WSACleanup();

}

在程序设计中通常希望对于数据交互方有没有数据传来做出反应,而不是单纯的阻塞等待在那里。这个时候可以用select先进行探测,一探测到有数据过来才调用recvfrom,如果超过时间则做出相应的超时处理,实现需要在上面的代码中recvfrom(原程序该函数阻塞)处稍作修改,修改代码如下:

fd_set readfds;
FD_ZERO(&readfds);//将指定的文件描述符集清空,在对文件描述符集合进行设置前,必须对其进行初始化,如果不清空,由于在系统分配内存空间后,通常并不作清空处理,所以结果是不可知的
FD_SET(socket1, &readfds); //用于在文件描述符集合中增加一个新的文件描述符。
struct timeval tv_out;
tv_out.tv_sec = 5;//等待5秒
tv_out.tv_usec = 0;
int selright=select(socket1 + 1, &readfds, NULL, NULL, &tv_out);
if (selright<=0)//为0时为超时,小于0时为错误,这两种情况皆非我们所想,故做出相同的处理
{
	printf("连接失败");
	return;
}
else
{
	if (recvfrom(socket1, buffer, sizeof(buffer), 0, (struct sockaddr*)&from, &fromlen) != SOCKET_ERROR)//阻塞接受客户端的请求
	{
		printf("连接成功,开始发送数据\n");
	}
}

当然如果希望循环等待,则每次都必须重新设置readfds

转载于:https://www.cnblogs.com/weixinhum/p/3916675.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/109764.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • CreatePipe()等函数创建管道来操纵控制台

    CreatePipe()等函数创建管道来操纵控制台#include  #include    #define BUFSIZE 4096   HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,    hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,    hInputFile, hStdout;   BO

    2022年7月14日
    18
  • SIGPIPE信号的产生及处理

    SIGPIPE信号的产生及处理SIGPIPE信号的产生在tcp四次挥手过程中,发送方向已经调用close()方法的socket一端写数据,会产生sigpipe错误。close():关闭读写两个方向,会导致sigpipe信号shutdown():可以选择关闭读/写方向,不会导致sigpipe信号SIGPIPE信号的解决方法直接忽略sigpipe信号voidhandle_for_sigpipe(){str…

    2022年7月17日
    22
  • java读写锁实现原理_java可重入锁原理

    java读写锁实现原理_java可重入锁原理一、synchronized和ReentrantLock的对比到现在,看到多线程中,锁定的方式有2种:synchronized和ReentrantLock。两种锁定方式各有优劣,下面简单对比一下:1、synchronized是关键字,就和if…else…一样,是语法层面的实现,因此synchronized获取锁以及释放锁都是Java虚拟机帮助用户完成的;ReentrantLock是类层面的…

    2022年8月12日
    10
  • javascript(js)小数精度丢失的解决方案

    原因:js按照2进制来处理小数的加减乘除,在arg1的基础上将arg2的精度进行扩展或逆扩展匹配,所以会出现如下情况.javascript(js)的小数点加减乘除问题,是一个js的bug如0.3*

    2021年12月25日
    40
  • php实现页面跳转的方式_html跳转代码

    php实现页面跳转的方式_html跳转代码在php中要实现跳转有很多方法,最常规的跳转方法就是使用header函数来操作了,当然也可以在php中输入js跳转形式,下面我来给大家介绍一下。PHP跳转代码如下复制代码header(“location:http://www.jquerycn.cn”);?>header函数使用PHP页面跳转一、header()函数header()函数是PHP中进…

    2022年8月13日
    6
  • 软件过程模型_软件测试过程模型

    软件过程模型_软件测试过程模型软件过程是为了获得高质量软件所需要完成的一系列任务的框架,它规定了完成各项任务的工作步骤。通常使用生命周期模型简洁地描述软件过程。生命周期模型规定了把生命周期划分成哪些阶段及各个阶段的执行顺序,因此,也称为过程模型。常见的过程模型有瀑布模型、快速原型模型、增量模型、螺旋模型、喷泉模型等。1.瀑布模型这个特点有两重含义:   1.必须等前一阶段的工作完成之后,才能开始后一阶段的工作;…

    2025年7月21日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号