0


服务端和客户端通信--UDP(含完整源代码)

UDP通信实验

实验设备:

目标系统:Windows

软件工具:vs2022/vc6/dev** **

实验要求:

  1. 完成UDP服务端和客户端的程序编写;
  2. 分别实现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);

发送端

  1. 建立套接字;

  2. 设置该套接字允许进行广播;

    3、将数据发送到广播地址中:sendto(buf,192.168.22.255);

    4、关闭

接收端(服务器)

  1. 建立套接字;
  2. 绑定广播ip地址(192.168.22.255)和端口号9999
  3. 接收数据
  4. 关闭

具体实现过程

广播发送端

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);

}

标签: udp 网络 网络协议

本文转载自: https://blog.csdn.net/qq_51782199/article/details/129529012
版权归原作者 添砖《java》 所有, 如有侵权,请联系我们删除。

“服务端和客户端通信--UDP(含完整源代码)”的评论:

还没有评论