unix domain socket使用demo

宋新知
2023-12-01

示例代码:

#include <stdio.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <libgen.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>

#define FILE_PATH_MAX_LEN 128
#define DATA_BUF_LEN	4096

char *process_name;

int srv_listen_sock = -1;
int srv_data_sock = -1;

int srv_waiting = 1;

char sock_file[FILE_PATH_MAX_LEN];

void get_sockaddr(struct sockaddr_un *addr)
{
	char *tmp;
	int ret;

	tmp = basename(process_name);
	assert(tmp != NULL);

	ret = snprintf(sock_file, FILE_PATH_MAX_LEN - 1, "/tmp/%s.sock", tmp);
	assert(ret <= FILE_PATH_MAX_LEN - 1);

	sock_file[FILE_PATH_MAX_LEN - 1] = 0;
	addr->sun_family = AF_UNIX;
	strcpy(addr->sun_path, sock_file);
}

void server_exit(int sig)
{
	printf("server is exit ...\n");
	if (srv_listen_sock != -1)
		close(srv_listen_sock);

	if (!srv_waiting && srv_data_sock != -1)
		close(srv_data_sock);

	unlink(sock_file);	
	exit(-1);
}
void run_server(void)
{
	int ret;
	char buf[DATA_BUF_LEN];
	struct sockaddr_un addr;
	struct stat sb;

	srv_listen_sock = socket(AF_UNIX, SOCK_STREAM, 0);
	assert(srv_listen_sock != -1);	

	get_sockaddr(&addr);

	if (stat(sock_file, &sb) != -1) {
		if ((sb.st_mode & S_IFMT) == S_IFSOCK)
			unlink(sock_file);
	}

	ret = bind(srv_listen_sock, (const struct sockaddr *)&addr,
			sizeof(struct sockaddr_un));
	assert(ret == 0);

	signal(SIGINT, server_exit);

	ret = listen(srv_listen_sock, 20);
	assert(ret == 0);

	printf("begin to wait for connecting ...\n");
	while ((srv_data_sock = accept(srv_listen_sock, NULL, NULL))) {
		srv_waiting = 0;

		recv(srv_data_sock, buf, sizeof(buf) - 1, 0);
		buf[sizeof(buf) - 1] = 0;
		printf("client says: %s\n", buf);

		strcpy(buf, "hello, client!\nbye-bye\n");
		send(srv_data_sock, buf, strlen(buf) + 1, 0);	
		close(srv_data_sock);

		srv_waiting = 1;
	}
}
void run_client(void)
{
	int data_sock;
	struct sockaddr_un addr;
	int ret;
	pid_t pid;
	char buf[DATA_BUF_LEN];

	data_sock = socket(AF_UNIX, SOCK_STREAM, 0);
	assert(data_sock != -1);

	get_sockaddr(&addr);

	ret = connect(data_sock, (const struct sockaddr *)&addr,
			sizeof(struct sockaddr_un));
	assert(ret == 0);
	
	snprintf(buf, DATA_BUF_LEN - 1, "I'm client, my pid is %d", getpid());
	send(data_sock, buf, strlen(buf) + 1, 0);	

	recv(data_sock, buf, sizeof(buf) - 1, 0);
	buf[sizeof(buf) - 1] = 0;
	
	printf("server replies: %s\n", buf);

	close(data_sock);
}

void usage(void)
{
	printf("%s: -s|-c\n", process_name);
	exit(-1);
}

int main(int argc, char *argv[])
{
	process_name = argv[0];

	if (argc != 2) {
		usage();
		return -1;
	}

	if (strcmp("-s", argv[1]) == 0) {
		run_server();
	} else if (strcmp("-c", argv[1]) == 0) {
		run_client();
	} else {
		usage();
		return -1;
	}

	return 0;
}

运行效果:
1)启动 server

$ ./main -s
begin to wait for connecting ...

2)启动若干个客户端

$ ./main -c
server replies: hello, client!
bye-bye

$ ./main -c
server replies: hello, client!
bye-bye

$ ./main -c
server replies: hello, client!
bye-bye

$ ./main -c
server replies: hello, client!
bye-bye

$ ./main -c
server replies: hello, client!
bye-bye

3)server 侧输出:

$ ./main -s
begin to wait for connecting ...
client says: I'm client, my pid is 29492
client says: I'm client, my pid is 29619
client says: I'm client, my pid is 29714
client says: I'm client, my pid is 29735
client says: I'm client, my pid is 29746

 类似资料: