UDP通信实验
实验设备:
目标系统:Windows
软件工具:vs2022/vc6/dev** **
实验要求:
- 完成UDP服务端和客户端的程序编写;
- 分别实现UDP一对一通信和广播通信功能。
实验内容:-static-libgcc
一对一通信:
服务器和客户端编程详细步骤:
1、加载/释放Winsock库,创建套接字(WSAStartup()/socket())。
加载方法:
WSADATA wsa;
/初始化socket资源/
if (WSAStartup(MAKEWORD(1,1),&wsa) != 0)
{
return; //代表失败
}
释放方法:
WSACleanup();
2、绑定IP地址、端口等信息到socket上。
server.sin_family = AF_INET;
server.sin_port = htons(12345); 本地监听端口
server.sin_addr.s_addr = inet_addr(ip);
![](https://img-blog.csdnimg.cn/097e4dd793bb43978bb6a5987bbcabcb.png)
3、发送数据。用返回的套接字和客户端进行通信(函数recvfrom()、sendto())
sendto():
int ret = recvfrom(int sockfd,void *buf,size_t len,0, struct sockaddr *to , int fromlen);
第一个参数为服务端的udp监听套接字
第二个参数为发送数据的缓冲区
第三个参数为缓存区的大小
第四个参数一般为0;
第五个参数一般为:记录地址信息,ip信息的结构体 。
第六个参数为:第五个参数的大小。
返回值:成功返回实际发送出去的信息的字节数,失败返回-1
recvfrom():
int ret = recvfrom(int sockfd,void *buf,size_t len,0, struct sockaddr *from,socket_t *fromlen);
第一个参数为服务端的udp监听套接字
第二个参数为接收数据的缓冲区
第三个参数为缓存区的大小
第四个参数一般为0;
第五个参数一般为:记录地址信息,ip信息的结构体 。
第六个参数为:第五个参数的大小,取地址。
返回值:成功返回接收到的信息的字节数,失败返回-1
服务端: 等待客户端接入.char buf[1024].
接收数据:recvfrom(Command_Sock,buf, …)
或
发送数据:sendto(Command_Sock,buf, …)
客户端: 请求与服务端连接.char buf[1024].
发送数据:sendto(Client_Sock,buf, …)
或
接收数据:recvfrom(Client_Sock,buf, …)
4、关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup())。
closesocket(Listen_Sock)
closesocket(Command_Sock)
注意:在dev里面编译会出现报错,需要在项目管理—参数—添加libws2_32.a动态库,该库在C:\Program Files (x86)\Dev-Cpp\MinGW64\x86_64-w64-mingw32\lib\libws2_32.a路径下。
代码执行结果****:
服务器端完整代码:
#include<stdio.h>
#include<stdlib.h>
#include<Winsock2.h>
int main (int agrc,char*argv[])
{
SOCKET socket1;
WSADATA wsaData;
int ErrorCode;
if(WSAStartup(MAKEWORD(2,1),&wsaData))// windows socket dll;
{
printf("Winsock启动失败!!\n");
WSACleanup();
return 0;
}
printf("Winsock start...\n");
const char* ip="127.0.0.1";
struct sockaddr_in server;
int len = sizeof(server);
server.sin_family = AF_INET;
server.sin_port = htons(12345);
server.sin_addr.s_addr = inet_addr(ip);
socket1 = socket(AF_INET,SOCK_DGRAM,0);
while (1)
{
char buffer[1024] = "/0";
printf("请输入要发送的信息:\n");
scanf("%s",buffer);
//printf("%s",buffer);
if(strcmp(buffer,"bye")==0)
{
printf("exit,bye!!\n");
Sleep(100);
closesocket(socket1);
break;
}
if(sendto(socket1,buffer,sizeof(buffer),0,(struct sockaddr*)&server,len)!=SOCKET_ERROR)
{
printf("发送完毕\n");
Sleep(100);
if(recvfrom(socket1,buffer,sizeof(buffer),0,(struct sockaddr*)&server,&len) != SOCKET_ERROR)
printf("recevie from server: %s\n",buffer);
}
}
closesocket(socket1);
system("pause");
return 0;
}
客户端完整代码:
#include<stdio.h>
#include<stdlib.h>
#include<Winsock2.h>
int main (int agrc,char*argv[])
{
SOCKET socket1;
WSADATA wsaData;
int ErrorCode;
if(WSAStartup(MAKEWORD(2,1),&wsaData))// windows socket dll;
{
printf("Winsock启动失败!!\n");
WSACleanup();
return 0;
}
printf("Winsock start...\n");
struct sockaddr_in local;
struct sockaddr_in client;
int len = sizeof(client);
local.sin_family = AF_INET;
local.sin_port = htons(12345); //the port need listened
local.sin_addr.s_addr = INADDR_ANY; //localhost
socket1 = socket(AF_INET,SOCK_DGRAM,0);
bind(socket1,(struct sockaddr*)&local,sizeof(local));
while (1)
{
char buffer[1024] = "/0";
printf("等待来自服务器发送的信息:\n");
if(recvfrom(socket1,buffer,sizeof(buffer),0,(struct sockaddr*)&client,&len) != SOCKET_ERROR)
{
printf("接收到的信息为: [%s]---%s\n",inet_ntoa(client.sin_addr),buffer);
//send sth to the client
sendto(socket1,buffer,sizeof(buffer),0,(struct sockaddr*)&client,len);
}
}
closesocket(socket1);
system("pause");
return 0;
}
UDP****广播通信:
服务器和客户端编程详细步骤:
分析:
广播通信是一对多的通信方式,会将消息分发给整个局域网内的所有主机,客户端需要绑定服务端广播使用的端口才能够接收到广播消息。广播地址以192.168.22.3网段为例:192.168.22.255 代表该网段的广播地址,发送给该地址的数据包被所有主机接收。
sendto("你好",192.168.22.255);
发送端:
建立套接字;
设置该套接字允许进行广播;
3、将数据发送到广播地址中:sendto(buf,192.168.22.255);
4、关闭
接收端(服务器):
- 建立套接字;
- 绑定广播ip地址(192.168.22.255)和端口号9999
- 接收数据
- 关闭
具体实现过程:
广播发送端:
1、创建数据报套接字 UDP
int socketfd = socket(AF_INET,SOCK_DGRAM,0);
2、设置socketfd套接字文件描述符的属性为 广播 。
int on=1;
setsockopt(sockfd , SOL_SOCKET,SO_BROADCAST,&on, sizeof(on));
3、发送数据 ,指定接收方为广播地址
struct sockaddr_in sendAddr;
sendAddr.sin_family = AF_INET;
sendAddr.sin_port = htons(9999);
sendAddr.sin_addr.s_addr = inet_addr("192.168.22.255");
sendto(sockfd,buf,strlen(buf),0,(struct sockaddr*)&sendAddr,sizeof(sendAddr));
4、关闭
close();
广播接收方(服务器端)****:
1****、创建用户数据报套接字
int
socketfd =
socket
(AF_INET,SOCK_DGRAM,
0
);
2、绑定(192.168.14.255)广播IP地址和端口号 (10000)
注意:绑定的端口必须和发送方指定的端口相同
struct sockaddr_in ownAddr;
ownAddr.sin_family = AF_INET;
ownAddr.sin_port = htons(10000);
**ownAddr.sin_addr.s_addr = htonl(INADDR_ANY);//INADDR_ANY(0.0.0.0) ****代表本机所有的地址 **
3、接收数据
recvfrom;
4、关闭套接字
close();
源代码:
发送端:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <Winsock2.h>
#include <windows.h>
#define GUANG_IP "192.168.22.255"
#define GUANG_PORT 9999
int main()
{
//建立套接字
int socket_fd = socket(AF_INET,SOCK_DGRAM,0);
if(socket_fd < 0)
{
perror("sokcet fail");
return -1;
}
//设置广播属性
int on=1;
setsockopt(socket_fd , SOL_SOCKET,SO_BROADCAST,&on, sizeof(on));
//给广播地址发送数据
struct sockaddr_in send_addr;
send_addr.sin_family = AF_INET;
send_addr.sin_port = htons(GUANG_PORT);
send_addr.sin_addr.s_addr = inet_addr(GUANG_IP);//广播地址
char buf[1024] = {0};
while(1)
{
bzero(buf,sizeof(buf));
scanf("%s",buf);
//发送的是实际的长度
sendto(socket_fd,buf,strlen(buf),0,(struct sockaddr *)&send_addr,sizeof(send_addr));
}
//关闭套接字
close(socket_fd);
}
接收端:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <Winsock2.h>
#include <windows.h>
#define GUANG_IP "192.168.22.255"
#define GUANG_PORT 9999
int main()
{
//建立套接字
int socket_fd = socket(AF_INET,SOCK_DGRAM,0);
if(socket_fd < 0)
{
perror("sokcet fail");
return -1;
}
//绑定广播地址
struct sockaddr_in my_addr;
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(GUANG_PORT);
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);//INADDR_ANY本机任意IP地址--常用方法
bind(socket_fd,(struct sockaddr *)&my_addr,sizeof(my_addr));
char buf[1024] = {0};
int ret;
struct sockaddr_in recv_addr;
socklen_t addrlen = sizeof(recv_addr);
while(1)
{
bzero(buf,sizeof(buf));//清空缓冲区
ret = recvfrom(socket_fd,buf,sizeof(buf),0,(struct sockaddr *)&recv_addr,&addrlen);
char *ip = inet_ntoa(recv_addr.sin_addr);
int port = ntohs(recv_addr.sin_port);
printf("[ip:%s port:%d] buf:%s ret:%d\n",ip,port,buf,ret);
}
//关闭套接字
close(socket_fd);
}
版权归原作者 添砖《java》 所有, 如有侵权,请联系我们删除。