unix套接字

下面的代码创建了一个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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值