下面是C语言实现UDP通信的完整攻略。
1. 确定需要使用的库和头文件
首先需要引入的头文件有:
#include <stdio.h> //标准输入输出库
#include <stdlib.h> //标准库
#include <string.h> //字符串处理库
#include <unistd.h> //Unix标准函数库
#include <sys/types.h> //Unix/Linux系统基本类型定义
#include <sys/socket.h> //套接字函数库
#include <netinet/in.h> //IP地址和端口号定义
2. 创建UDP套接字
在准备使用UDP套接字之前,需要先调用 socket()
方法创建一个套接字。该方法接受三个参数:
int socket(int domain, int type, int protocol);
其中:
domain
:协议域(通常是AF_INET
,表示TCP/IP协议);type
:套接字类型(通常是SOCK_DGRAM
,表示UDP套接字);protocol
:协议类型,通常为0
,表示默认协议。
创建UDP套接字的代码示例如下:
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
3. 套接字绑定地址和端口号
在创建UDP套接字后,需要将其绑定到一个本地地址和端口号上,以便于其他进程能够发送数据到该端口。可使用 bind()
方法进行绑定,该方法接受两个参数:
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
其中:
sockfd
:创建好的套接字;addr
:要绑定的地址和端口号;addrlen
:地址和端口号的长度。
代码示例如下:
struct sockaddr_in addr;
addr.sin_family = AF_INET; //协议域
addr.sin_port = htons(PORT); //端口号
addr.sin_addr.s_addr = htonl(INADDR_ANY);//IP地址(在本机的任何一个IP上都能够接收到信息)
if(bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) == -1) {
printf("Bind Error.\n");
return 0;
}
4. 发送UDP数据
在UDP通信中,发送数据时使用 sendto()
方法。该方法接受四个参数:
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
其中:
sockfd
:创建好的套接字;buf
:发送的数据内容;len
:发送的数据长度;flags
:调用操作方式,通常为0
;dest_addr
:目标地址和端口号;addrlen
:目标地址和端口号的长度。
代码示例如下:
char sendbuf[1024] = "hello, this is a message from client.";
int sendbytes = sendto(sockfd, sendbuf, strlen(sendbuf), 0, (struct sockaddr *)&addr, sizeof(struct sockaddr));
5. 接收UDP数据
在UDP通信中,接收数据时使用 recvfrom()
方法。该方法接受五个参数:
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
其中:
sockfd
:创建好的套接字;buf
:接收到的数据内容;len
:接收数据的最大长度;flags
:调用操作方式,通常为0
;src_addr
:发送方的地址和端口号;addrlen
:发送方的地址和端口号的长度。
代码示例如下:
char recvbuf[1024] = "";
struct sockaddr_in fromaddr;
socklen_t fromlen = sizeof(fromaddr);
int recvbytes = recvfrom(sockfd, recvbuf, 1024, 0, (struct sockaddr *)&fromaddr, &fromlen);
printf("Received message: %s\n", recvbuf);
示例说明
以下是一个简单的UDP客户端和服务器示例,可以直接运行在Linux上:
服务器
服务器会监听一个指定的端口,等待客户端发送信息。每当接收到客户端发来的信息时,会将消息打印出来,并向客户端回复一条信息。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORT 8888
int main(int argc, char *argv[]) {
int sockfd;
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
printf("Socket Error.\n");
return 0;
}
struct sockaddr_in addr;
addr.sin_family = AF_INET; //协议域
addr.sin_port = htons(PORT); //端口号
addr.sin_addr.s_addr = htonl(INADDR_ANY);//IP地址(在本机的任何一个IP上都能够接收到信息)
if(bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) == -1) {
printf("Bind Error.\n");
return 0;
}
printf("======Waiting for client's request======\n");
char sendbuf[1024] = "";
char recvbuf[1024] = "";
struct sockaddr_in fromaddr;
socklen_t fromlen = sizeof(fromaddr);
while(1) {
//receieve the message
int recvbytes = recvfrom(sockfd, recvbuf, 1024, 0, (struct sockaddr *)&fromaddr, &fromlen);
if(recvbytes == -1) {
printf("Receive Error.\n");
break;
}
recvbuf[recvbytes] = 0;
char *client_ip = inet_ntoa(fromaddr.sin_addr);
printf("[Received From %s:%u]> %s\n", client_ip, ntohs(fromaddr.sin_port), recvbuf);
//send back to client
sprintf(sendbuf, "Your message has been received.");
int sendbytes = sendto(sockfd, sendbuf, strlen(sendbuf), 0, (struct sockaddr *)&fromaddr, fromlen);
if(sendbytes == -1) {
printf("Send Error.\n");
break;
}
}
close(sockfd);
return 0;
}
客户端
客户端会向服务器发送一条信息,并等待服务器回复。当收到服务器的回复时,会将消息打印出来。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORT 8888
struct sockaddr_in addr;
int main(int argc, char *argv[]) {
int sockfd;
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
printf("Socket Error.\n");
return 0;
}
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
char sendbuf[1024] = "hello, this is a message from client.";
char recvbuf[1024] = "";
int sendbytes = sendto(sockfd, sendbuf, strlen(sendbuf), 0, (struct sockaddr *)&addr, sizeof(struct sockaddr));
if(sendbytes == -1) {
printf("Send Error.\n");
return 0;
}
int recvbytes = recvfrom(sockfd, recvbuf, 1024, 0, (struct sockaddr *)&addr, (socklen_t *)&sizeof(struct sockaddr));
if(recvbytes == -1) {
printf("Receive Error.\n");
return 0;
}
recvbuf[recvbytes] = 0;
printf("Receive: %s\n", recvbuf);
close(sockfd);
return 0;
}
这样,我们就成功地用C语言实现了UDP通信。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言实现UDP通信 - Python技术站