在main函数中,先创建了一个线程来做UDP服务器,然后创建socket向UDP服务器发送和接收数据,最终直接使用给定的ip和端口号,向搭建好的rsyslog服务器发送数据,可以看到数据。为了省事,所有的东西都在一个文件中写完了,包括UDP服务器,UDP客户端。
代码如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define UDP_TEST_PORT 2234
#define UDP_SERVER_IP "127.0.0.1"
#define MAX_LINE 1024
/**********************************************************************
* 功能描述:向给定ip和端口号发送udp字符串
* 输入参数: char *ip:ip地址
* int port:端口号
* char* str:发送的字符串
* 输出参数:无
* 返 回 值: int:发送结果
* 其它说明:无
***********************************************************************/
int send_udp_str(char *ip, int port, char* str) {
int ret = 0;
if (str == NULL) {
ret = -1;
return ret;
}
struct sockaddr_in server;
int sockfd = 0;
int server_len = sizeof(struct sockaddr_in);
/* setup a socket,attention: must be SOCK_DGRAM */
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket");
ret = -1;
return ret;
}
/*complete the struct: sockaddr_in*/
bzero(&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = inet_addr(ip);
/* send the string to server*/
if (sendto(sockfd, str, strlen(str), 0, (struct sockaddr *) &server,
server_len) < 0) {
printf("sendto error\n");
ret = -2;
}
close(sockfd);
return ret;
}
/**********************************************************************
* 功能描述:接收udp字符串
* 输入参数: int sockfd:fd
struct sockaddr_in server
* char* buf:接收的字符串存储空间,需要先分配好内存,如 char buf[1024];
* 输出参数:无
* 返 回 值: int:结果
* 其它说明:无
***********************************************************************/
int recv_udp_str_by_fd(int sockfd, struct sockaddr_in server, char* buf) {
int ret = 0;
if (buf == NULL) {
ret = -1;
return ret;
}
memset(buf, 0, sizeof(buf));
int len = 0;
int server_len = sizeof(struct sockaddr_in);
/* recieve the string from server*/
len = recvfrom(sockfd, buf, 1024, 0, (struct sockaddr *) &server,
&server_len);
if (len < 0) {
printf("recvfrom error\n");
ret = -1;
return ret;
}
// printf("Received len = %d \n", len);
return ret;
}
/**********************************************************************
* 功能描述:发送udp字符串
* 输入参数: int sockfd:fd
struct sockaddr_in server
* char* str:发送的字符串
* 输出参数:无
* 返 回 值: int:结果
* 其它说明:无
***********************************************************************/
int send_udp_str_by_fd(int sockfd, struct sockaddr_in server, char* str) {
int ret = 0;
if (str == NULL) {
ret = -1;
return ret;
}
int len = 0;
int server_len = sizeof(struct sockaddr_in);
/* send the string to server*/
if (sendto(sockfd, str, strlen(str), 0, (struct sockaddr *) &server,
server_len) < 0) {
printf("sendto error\n");
ret = -1;
}
return ret;
}
/**********************************************************************
* 功能描述:开启一个UDP服务端
* 输入参数: char *ip:ip地址
* int port:端口号
* 输出参数:无
* 返 回 值: int:结果
* 其它说明:无
***********************************************************************/
int UDP_Server_main(char* ip, int port) {
//创建套接字
int sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
perror("socket");
// exit(1);
return -1;
}
//将套接字与ip地址和端口号进行绑定
struct sockaddr_in local;
local.sin_family = AF_INET;
local.sin_port = htons(port);
local.sin_addr.s_addr = inet_addr(ip);
if (bind(sock, (struct sockaddr*) &local, sizeof(local)) < 0) {
perror("bind");
// exit(2);
return -2;
}
char buf[1024];
struct sockaddr_in client;
socklen_t len = sizeof(client);
char* msg = "Have a goog day";
char msg_back[1024];
while (1) {
//读取数据
int r = recvfrom(sock, buf, sizeof(buf) - 1, 0,
(struct sockaddr*) &client, &len);
if (r < 0) {
perror("recvfrom");
// exit(3);
} else {
buf[r] = 0;
printf("[%s : %d]# %s\n", inet_ntoa(client.sin_addr),
ntohs(client.sin_port), buf);
sprintf(msg_back, "%s: %s", msg, buf);
//回送数据
if (sendto(sock, msg_back, strlen(msg_back), 0,
(struct sockaddr*) &client, len) < 0) {
perror("sendto");
// exit(4);
}
if (strcmp(buf, "end") == 0) {
break;
}
}
}
printf("receive end from [%s : %d]\n", inet_ntoa(client.sin_addr),
ntohs(client.sin_port));
close(sock);
return 0;
}
// 开启UDPServer线程的函数,注意配置的ip和port与客户端一致
int UDP_Server_main_thread() {
printf("UDP_Server_main_thread begin\n");
int ret = UDP_Server_main(UDP_SERVER_IP, UDP_TEST_PORT);
printf("UDP_Server_main_thread end ret = %d\n", ret);
return ret;
}
int main(int argC, char* arg[]) {
int ret = 0;
char *ipAddr = UDP_SERVER_IP;
int port = UDP_TEST_PORT;
char sendStr[MAX_LINE] = {0}; //默认发送串
char buf[MAX_LINE] = {0}; //接收缓冲区
pthread_t tid;
int err;
//----------------创建UDP服务端线程----------------
err = pthread_create(&tid, NULL, UDP_Server_main_thread, NULL);
if (err != 0) {
perror(" fail to create thread ");
return -1;
}
sleep(1);
// ----------------新建socket,发送UDP包到服务端线程----------------
struct sockaddr_in server;
/*complete the struct: sockaddr_in*/
bzero(&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = inet_addr(ipAddr);
int sockfd = 0;
/* setup a socket,attention: must be SOCK_DGRAM */
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket");
err = -1;
return err;
}
int count = 1;
while (1) {
sprintf(sendStr, "client-%d|aaa", count);
send_udp_str_by_fd(sockfd, server, sendStr);
recv_udp_str_by_fd(sockfd, server, buf);
printf("Receive from server: %s\n", buf);
count +=10;
if(count > 100)
break;
}
send_udp_str(ipAddr, port, "aaaaaatest_send");
send_udp_str(ipAddr, port, "bbbbb");
send_udp_str(ipAddr, port, "end");
pthread_join(tid, NULL);
// -------------发送UDP包到syslog服务端----------------
ipAddr = "192.168.3.39";
port = 514;
char tmpStr[4096];
int count1 = 1;
while(count1 <= 10)
{
sprintf(tmpStr, "hahaha,to syslog-%d", count1);
ret = send_udp_str(ipAddr, port, tmpStr);
printf("count = %d; ret = %d\n", count1, ret);
sleep(1);
count1++;
}
return 0;
}
$ sudo apt-get install rsyslog
直接一步步安装就好
$ sudo vim /etc/rsyslog.conf
修改内容
先找到514端口相关内容,然后取消注释(删除前面的#),改为如下:
# provides UDP syslog reception
module(load="imudp")
input(type="imudp" port="514")
# provides TCP syslog reception
module(load="imtcp")
input(type="imtcp" port="514")
查看结果:
$ sudo netstat -tulpn | grep rsyslog
tcp 0 0 0.0.0.0:514 0.0.0.0:* LISTEN 2786/rsyslogd
tcp6 0 0 :::514 :::* LISTEN 2786/rsyslogd
udp 0 0 0.0.0.0:514 0.0.0.0:* 2786/rsyslogd
udp6 0 0 :::514 :::* 2786/rsyslogd
可以看到tcp和udp的514端口都打开了。
$ sudo service rsyslog restart
$ sudo vim /etc/default/rsyslog
改为如下:
# Options for rsyslogd
# -x disables DNS lookups for remote messages
# See rsyslogd(8) for more details
RSYSLOGD_OPTIONS="-r"
$ tail -f /var/log/syslog
运行UDP程序,可以看到结果:
$ tail -f /var/log/syslog
May 24 15:56:26 192.168.3.51 hahaha,to syslog-1
May 24 15:56:27 192.168.3.51 hahaha,to syslog-2
May 24 15:56:28 192.168.3.51 hahaha,to syslog-3
May 24 15:56:29 192.168.3.51 hahaha,to syslog-4
May 24 15:56:30 192.168.3.51 hahaha,to syslog-5
May 24 15:56:31 192.168.3.51 hahaha,to syslog-6
May 24 15:56:32 192.168.3.51 hahaha,to syslog-7
May 24 15:56:33 192.168.3.51 hahaha,to syslog-8
May 24 15:56:34 192.168.3.51 hahaha,to syslog-9
May 24 15:56:35 192.168.3.51 hahaha,to syslog-10
Ubuntu的rsyslog服务器搭建参考:https://blog.csdn.net/martin_ywz/article/details/52523094