golang和c通过unix域实现双向通信

go的代码如下:

package main

import (
	"fmt"
	"net"
	"bufio"
	"os"
	"syscall"
)

func writeUnix(listener *net.UnixConn,dstAddr *net.UnixAddr) {
	for {
		bio := bufio.NewReader(os.Stdin)
		buf,_,_:= bio.ReadLine()
		_, err := listener.WriteToUnix(buf, dstAddr)
		checkError(err)
	}
}

func readUnix(listener *net.UnixConn) {
	for {
		buf :=make([]byte, 1400)
		size, remote, err := listener.ReadFromUnix(buf)
		checkError(err)
		fmt.Println("recv:", string(buf[:size]), " from ", remote.String())
	}
}
func checkError(err error) {
	if err != nil {
		fmt.Printf("Error: %s\n", err.Error())
		os.Exit(1)
	}
}
func runUnix() {

	addr, err := net.ResolveUnixAddr("unixgram", "/tmp/gsocket")
	checkError(err)
	syscall.Unlink("/tmp/gsocket")
	listener, err := net.ListenUnixgram("unixgram", addr)
	defer listener.Close()
	checkError(err)
	dstAddr, err := net.ResolveUnixAddr("unixgram", "/tmp/csocket")

	//send to its subs
	go readUnix(listener)
	go writeUnix(listener,dstAddr)
	select{}
}

func main(){
	runUnix()
}

c的代码如下:

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

#define  err_log(errlog)  do{perror(errlog); exit(1);}while(0)
#define   N  128
void * psend(void *a);
void * precv(void *a);
int main(int argc, const char *argv[])
{
	pthread_t send;
	pthread_t recv;
	if(pthread_create(&send, NULL, psend, NULL) == -1)
	{
		puts("fail to create pthread send");
		exit(1);
	}
	if(pthread_create(&recv, NULL, precv, NULL) == -1){
		puts("fail to create pthread t1");
		exit(1);
	}

	// 等待线程结束
	void * result;
	if(pthread_join(send, &result) == -1){
		puts("fail to recollect send");
		exit(1);
	}

	if(pthread_join(recv, &result) == -1){
		puts("fail to recollect recv");
		exit(1);
	}

	return 0;
}
void * psend(void *a)
{
	int sockfd;
	struct sockaddr_un serveraddr;
	struct sockaddr_un clientaddr;
	socklen_t addrlen = sizeof(clientaddr);
	char buf[N] = {};
	if((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
	{
		err_log("fail to socket");
	}
	serveraddr.sun_family = AF_UNIX;
	strcpy(serveraddr.sun_path, "/tmp/gsocket");
	while(1)
	{
		bzero(buf,N);
		fgets(buf, N, stdin);
		buf[strlen(buf)-1] = '\0';

		if(sendto(sockfd, buf, N, 0, (struct sockaddr *)&serveraddr, addrlen) < 0)
		{
			err_log("fail to sendto");
		}

		if(strncmp(buf, "quit", 4) == 0)
		{
			break;
		}
	}
	close(sockfd);
}
void * precv(void *a)
{
	int sockfd;
	struct sockaddr_un serveraddr;
	struct sockaddr_un clientaddr;
	socklen_t addrlen = sizeof(clientaddr);
	char buf[N] = {};

	if((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
	{
		err_log("fail to socket");
	}
	serveraddr.sun_family = AF_UNIX;
	strcpy(serveraddr.sun_path, "/tmp/csocket");
	unlink("/tmp/csocket");
	if(bind(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0)
	{
		err_log("fail to bind");
	}
	while(1)
	{
		bzero(buf,N);
		if(recvfrom(sockfd, buf, N, 0, (struct sockaddr*)&clientaddr, &addrlen) < 0)
		{
			err_log("fail to recvfrom");
		}
		printf("recv: %s from %s\n", buf, clientaddr.sun_path);
		if(strncmp(buf, "quit", 4) == 0)
		{
			break;
		}
	}
	close(sockfd);
}

golang的监听socket是/tmp/gsocket, c的监听socket是/tmp/csocket.通过命令行输入,实现跨进程通信.通过多线程,实现双向并行通信.

猜你喜欢

转载自blog.csdn.net/dong_beijing/article/details/83388713