Golang socket编程

Golang socket编程,第1张

用Go语言实现unix socket通信。


这里用Go语言写服务端,C语言写客户端。


Go
package main

import (
	"net"
	"os"
	"os/signal"
	"syscall"

	logs "github.com/sirupsen/logrus"
)

func main() {
	os.Remove("/tmp/sock")
	conn, err := net.ResolveUnixAddr("unix", "/tmp/sock")
	if err != nil {
		logs.Error(err)
	}

	listener, err := net.ListenUnix("unix", conn)
	if err != nil {
		logs.Error(err)
	}

	go func() {
		<-HandleSIGINTKILL()

		logs.Info("SIGINTKILL")
		logs.Info("exit main")

		os.Remove("/tmp/sock")

		os.Exit(0)
	}()

	for {
		conn, err := listener.Accept()
		if err != nil {
			logs.Error(err)
		}

		go handleConnection(conn)
	}
}

func handleConnection(conn net.Conn) {
	buf := make([]byte, 1024)
	for {
		n, err := conn.Read(buf)
		
		if err == io.EOF {
			logs.Info("EOF")
			break
		}
	
		if err != nil {
			logs.Error(err)
		}

		logs.Info(string(buf[:n]))
	}
}

func HandleSIGINTKILL() chan os.Signal {
	sig := make(chan os.Signal, 1)

	signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)

	return sig
}

C
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define BUFFER_SIZE 1024
const char *filename = "/tmp/sock";

void *thread_recv(void *ptr)
{
    int sock_fd = *(int *)ptr;
    char buffer[128] = {0};
    while (1)
    {
        int ret = recv(sock_fd, buffer, 128, 0);
        if (ret <= 0)
        {
            printf("recv error: %s\n", strerror(ret));
            close(sock_fd);
            exit(EXIT_FAILURE);
        } else {
            printf("%s\n", buffer);
        }
    }
}

int main()
{
    while (1)
    {
        struct sockaddr_un un;
        int sock_fd;
        char buffer[BUFFER_SIZE] = "hello world";
        un.sun_family = AF_UNIX;
        strcpy(un.sun_path, filename);
        sock_fd = socket(AF_UNIX, SOCK_STREAM, 0);
        if (sock_fd < 0)
        {
            printf("Request socket failed\n");
            return -1;
        }
        if (connect(sock_fd, (struct sockaddr *)&un, sizeof(un)) < 0)
        {
            printf("connect socket failed\n");
            return -1;
        }

        pthread_t pth;

        pthread_create(&pth, NULL, thread_recv, (void *)(&sock_fd));

        while (1)
        {
            memset(buffer, 0, BUFFER_SIZE);
            fgets(buffer, BUFFER_SIZE, stdin);

            printf("send data: %s\n", buffer);

            int error = 0;
            socklen_t len = sizeof(error);
            int retval = getsockopt(sock_fd, SOL_SOCKET, SO_ERROR, &error, &len);

            if (retval != 0)
            {
                /* there was a problem getting the error code */
                fprintf(stderr, "error getting socket error code: %s\n", strerror(retval));
                return 0;
            }

            if (error != 0)
            {
                /* socket has a non zero error status */
                fprintf(stderr, "socket error: %s\n", strerror(error));
                return 0;
            }

            ssize_t size = send(sock_fd, buffer, BUFFER_SIZE, MSG_NOSIGNAL);

            if (size <= 0)
            {
                // close(sock_fd);
                // return 0;
                printf("send data failed.\n");
            }
        }
    }

    return 0;
}
Go版客户端
package main

import (
	"bufio"
	"io"
	"net"
	"os"

	logs "github.com/sirupsen/logrus"
)

func main() {
	addr, err := net.ResolveUnixAddr("unix", "/tmp/sock")
	if err != nil {
		logs.Error(err)
	}

	conn, err := net.DialUnix("unix", nil, addr)
	if err != nil {
		logs.Error(err)
	}

	buf := make([]byte, 1024)
	for {
		input := bufio.NewReader(os.Stdin)
		str, _ := input.ReadString('\n')
		conn.Write([]byte(str))

		num, err := conn.Read(buf)
		if err == io.EOF {
			logs.Info("EOF")
			break
		}
		logs.Info(string(buf[:num]))
	}
}
测试

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/634433.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-16
下一篇 2022-04-16

发表评论

登录后才能评论

评论列表(0条)

保存