golang和c通過unix域實現雙向通訊
阿新 • • 發佈:2018-11-02
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.通過命令列輸入,實現跨程序通訊.通過多執行緒,實現雙向並行通訊.