Linux UDP套接字编程
一 UDP套接字编程的基本步骤
服务端编程的步骤如下:
- 创建套接字描述符(socket)。
- 设置服务器的IP地址和端口号(需要转换为网络字节序的格式)。
- 将套接字描述符绑定服务器地址(bind)。
- 从套接字描述符读取来自客户端的请求并取得客户端的地址(recvfrom)。
- 向套接字描述符写入应答并发送给客户端(sendto)。
- 回到步骤4,等待读取下一个来自客户端的请求。
客户端编程的步骤如下:
- 创建套接字描述符(socket)。
- 设置服务器的IP地址和端口号(需要转换为网络字节序的格式)。
- 向套接字描述符写入请求并发送给服务端(sendto)。
- 从套接字描述符读取来自服务器的应答(recvfrom)。
- 关闭套接字描述符(close)。
二 服务端程序:
#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
#include <sys/socket.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
char g_ReadBuf[50];
int main()
{
int sockfd;
int size;
int ret;
int on = 1;
struct sockaddr_in saddr;
struct sockaddr_in raddr;
// 设置地址信息,ip信息
size = sizeof(struct sockaddr_in);
bzero(&saddr, size);
saddr.sin_family = AF_INET;
saddr.sin_port = htons(8888);
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
// 创建UDP套接字
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0)
{
perror("error: socket failed");
return -1;
}
// 设置端口复用
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
// 绑定地址信息,ip信息
ret = bind(sockfd, (struct sockaddr *)&saddr, sizeof(struct sockaddr));
if (ret < 0)
{
perror("error: bind failed");
return -1;
}
// 循环接收客户端发来的消息
socklen_t val = sizeof(struct sockaddr);
while (1)
{
puts("info: waiting data");
ret = recvfrom(sockfd, g_ReadBuf, 50, 0, (struct sockaddr *)&raddr, &val);
if (ret < 0)
{
perror("error: recvfrom failed");
}
printf("info: the data is :%s\n", g_ReadBuf);
bzero(g_ReadBuf, 50);
}
// 关闭upd套接字,这里不可达
close(sockfd);
return 0;
}
通过一个while循环来等待客户端发来的消息。没有数据过来时,就在recvfrom函数上阻塞着。
三 客户端程序:
#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
#include <sys/socket.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
char g_WriteBuf[50];
int main()
{
int sockfd;
int size;
int ret;
int on = 1;
struct sockaddr_in saddr;
struct sockaddr_in raddr;
// 设置地址信息,ip信息
size = sizeof(struct sockaddr_in);
bzero(&saddr, size);
saddr.sin_family = AF_INET;
saddr.sin_port = htons(8888);
saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0)
{
perror("error: socket failed");
return -1;
}
// 设置端口复用
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
// 循环发送消息给服务端
while (1)
{
puts("info: Please enter data:");
scanf("%s", g_WriteBuf);
ret = sendto(sockfd, g_WriteBuf, 50, 0, (struct sockaddr *)&raddr, sizeof(struct sockaddr));
if (ret < 0)
{
perror("error: send failed");
}
bzero(g_WriteBuf, 50);
}
// 关闭upd套接字,这里不可达
close(sockfd);
return 0;
}
使用一个while循环来等待用户输入信息,输入后就把信息发送出去。