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] = "
<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>
"; 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
#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();
}
"; 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

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • word2016论文不同章节设置页眉页码方法[通俗易懂]

    word2016论文不同章节设置页眉页码方法[通俗易懂]最近在写硕士论文需要调整页眉页脚,并且每一章都不一样,网上搜的教程都有点复杂,现在自己弄懂了,把它记录下来:1,设置不同章节不同页眉2,设置奇偶页不同2,设置页码从第xx页开始本文以word2016为例,讲述以上3点的设置方法:1,设置不同章节不同页眉首先是常规操作,点击word上方插入–页眉和页码这样页眉和页码就在word上显示出来了然而仅这样操作所有…

    2022年10月29日
  • pycharm设置背景颜色_idea自定义背景颜色

    pycharm设置背景颜色_idea自定义背景颜色pycharm原始的背景是白底黑字或者黑底白字,我都不是很喜欢。我配置的是豆沙绿背景,字还是黑字,效果还不错,这种是比较护眼的。如图:  具体操作如下:File->Settings->Editor->Colors&Fonts->General->Text->Defaulttext然后修改background的颜色,配置如下图:

  • smalldatetime数据类型「建议收藏」

    smalldatetime数据类型「建议收藏」smalldatetime共需要4个字节,其中两个字节表示1900-1-1之后的所有天数,另外两个字节表示午夜后一分钟为单位的时间,支持范围从1900-1-1到2079-6-6转载于:https://www.cnblogs.com/Junelee1211/archive/2011/07/08/2100694.html…

  • v型密封圈的使用方法_橡胶密封圈标准

    v型密封圈的使用方法_橡胶密封圈标准充气密封圈到底能够密封什么呢?到底什么地方需要充气密封圈呢?我们带着问题来看下面的文章:一、充气密封圈定义简介:充气密封圈在自然状态下密封圈的可伸缩部分隐藏在凹槽内,当通过气嘴向密封圈充气时,密封圈因受内压力作用而发生变形,中间部分向外胀起,与另一密封面紧密接触,从而起到密封作用。需要解除密封状态时,通过气嘴排出密封圈内高压气体,膨胀部分受橡胶弹性作用自动回缩到凹槽内,与密封面脱离。二、充气密封圈…

  • append函数的用法[通俗易懂]

    append函数的用法[通俗易懂]append()函数类似于尾插就是给元素后面追加一个字符串stringstr;stringstr2=“123”;1.str.append(str2);就是给str后面追加一个str2即输出为123str.strappend(str2,1,1);就是给后面追加上str2中从第二个元素开始连续一个元素1232str.append(“abc”);就是给str后面追加上abc1232abcstr.append(“123456”,6);就是给str后面加上字符串

  • 闫学灿acwing_用标号法求网络最大流

    闫学灿acwing_用标号法求网络最大流给定一个包含 n 个点 m 条边的有向图,并给定每条边的容量,边的容量非负。图中可能存在重边和自环。求从点 S 到点 T 的最大流。输入格式第一行包含四个整数 n,m,S,T。接下来 m 行,每行三个整数 u,v,c,表示从点 u 到点 v 存在一条有向边,容量为 c。点的编号从 1 到 n。输出格式输出点 S 到点 T 的最大流。如果从点 S 无法到达点 T 则输出 0。数据范围2≤n≤1000,1≤m≤10000,0≤c≤10000,S≠T输入样例:7 14 1 71 2

发表回复

您的电子邮箱地址不会被公开。

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