用Go语言实现unix socket通信。
这里用Go语言写服务端,C语言写客户端。
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]))
}
}
测试
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)