示例代码:
#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