使用C写socket收发UDP包,并发送UDP包到syslog中

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lllkey/article/details/80435802

一、UDP相关代码

在main函数中,先创建了一个线程来做UDP服务器,然后创建socket向UDP服务器发送和接收数据,最终直接使用给定的ip和端口号,向搭建好的rsyslog服务器发送数据,可以看到数据。为了省事,所有的东西都在一个文件中写完了,包括UDP服务器,UDP客户端。

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>

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

}


二、Ubuntu的rsyslog服务器搭建过程:

1 安装rsyslog

$ sudo apt-get install rsyslog

直接一步步安装就好


2 修改配置文件,打开接收514端口数据

$ 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端口都打开了。


3 重启rsyslog服务

$ sudo service rsyslog restart


4 修改启动配置文件

$ sudo vim /etc/default/rsyslog

改为如下:

# Options for rsyslogd
# -x disables DNS lookups for remote messages
# See rsyslogd(8) for more details
RSYSLOGD_OPTIONS="-r"


5 查看结果

$ 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


UDP参考:http://velep.com/archives/934.html

Ubuntu的rsyslog服务器搭建参考:https://blog.csdn.net/martin_ywz/article/details/52523094


展开阅读全文

没有更多推荐了,返回首页