下面的代码创建了一个server和一个client。
client发送两个请求:echo和exit。
server收到exit立即退出,其他请求则返回一个固定的字符串作为回馈。
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <sys/un.h>
int queryUnixSocketFD(int sockfd){
struct sockaddr_un addr_query;
socklen_t len = sizeof(addr_query);
if (getsockname(sockfd, (struct sockaddr*)&addr_query, &len) == -1){
perror("cannot get sock name");
return 1;
}
printf("bound name = %s, returned len = %d\n", addr_query.sun_path, len);
return 0;
}
int main(){
// define socket file to use
const char *path = "/var/leon/unix.sock";
// create the socket & bind to socket file
int sockfd = socket(AF_LOCAL, SOCK_STREAM, 0);
if (sockfd == -1){
perror("failed to create socket");
return 1;
}
unlink(path);
struct sockaddr_un addr;
bzero(&addr, sizeof(addr));
addr.sun_family = AF_LOCAL;
strcpy(addr.sun_path, path);
// printf("path:%s, sun_len:%lu\n", addr1.sun_path, SUN_LEN(&addr1));
if (bind(sockfd, (struct sockaddr*)&addr, SUN_LEN(&addr)) == -1){
perror("bind failed");
printf("errno:%d\n", errno);
return 1;
}
// get bind address info
// queryUnixSocketFD(sockfd);
pid_t son_pid = fork();
if (son_pid == 0){
sleep(1);
// client
close(sockfd);// it's useless for normal clients!
// write 'echo'
int fd = socket(AF_LOCAL, SOCK_STREAM, 0);
if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1){
perror("connect failed");
exit(-1);
}
if (write(fd, "echo", 4) == -1){
perror("client write failed");
exit(-1);
}
char buf[32];
int bytes = read(fd, buf, sizeof(buf));
if (bytes == -1){
perror("client read failed");
exit(-1);
}
buf[bytes] = '\0';
printf("get content: %s\n", buf);
close(fd);
// write 'exit'
fd = socket(AF_LOCAL, SOCK_STREAM, 0);
if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1){
perror("connect failed");
exit(-1);
}
if (write(fd, "exit", 4) == -1){
perror("client write failed");
exit(-1);
}
close(fd);
printf("client exit\n");
}else{
printf("server started\n");
// server
listen(sockfd, 5);
sockaddr_un client_addr;
socklen_t client_addr_len = sizeof(client_addr);
while(1){
printf("waiting...\n");
// accept request
int client_fd = accept(sockfd, (struct sockaddr*)&client_addr, &client_addr_len);
if (client_fd == -1){
close(sockfd);
perror("accept failed");
break;
}
// receive
char buf[32];
if (read(client_fd, buf, sizeof(buf)) == -1){
close(client_fd);
perror("server read failed");
exit(-1);
}
if (strncmp(buf, "exit", 4) == 0){
close(client_fd);
printf("server exit\n");
exit(0);
}
// create a handler process to do the job
pid_t son_pid = fork();
if (son_pid != 0){continue;}
// handler thread
printf("handler thread started\n");
const char *echo_content = "lightserver v1.0";
if (write(client_fd, echo_content, strlen(echo_content)) == -1){
close(client_fd);
perror("write to client failed");
exit(-1);
}
exit(0);
}
printf("server exit\n");
}
return 0;
}