精华内容
下载资源
问答
  • linux socket进程通信

    万次阅读 2012-03-16 10:08:39
    socket进程通信与网络通信使用的是统一套接口,只是地址结构与某些参数不同。 一。创建socket服务端的流程如下: (1)创建socket,类型为AF_LOCAL或AF_UNIX,表示用于进程通信: int server_fd; int client_...

    socket进程通信与网络通信使用的是统一套接口,只是地址结构与某些参数不同。

    一。创建socket服务端的流程如下:

    (1)创建socket,类型为AF_LOCAL或AF_UNIX,表示用于进程通信:

    	int server_fd;
    	int client_fd;//client file descriptor
    	struct sockaddr_un server_addr; 
    	struct sockaddr_un client_addr;
    	size_t server_len,client_len;
    
    	//cteate server socket
    	//delete old socket file
    	unlink(SERVER_NAME);
    	if ((server_fd = socket(AF_UNIX,  SOCK_STREAM,  0)) == -1) {
    		perror("socket");
    		exit(1);
    	}

    (2)命名socket。这里面有一个很关键的东西,socket进程通信命名方式有两种。一是普通的命名,socket会根据此命名创建一个同名的socket文件,客户端连接的时候通过读取该socket文件连接到socket服务端。这种方式的弊端是服务端必须对socket文件的路径具备写权限,客户端必须知道socket文件路径,且必须对该路径有读权限。另外一种命名方式是抽象命名空间,这种方式不需要创建socket文件,只需要命名一个全局名字,即可让客户端根据此名字进行连接。后者的实现过程与前者的差别是,后者在对地址结构成员sun_path数组赋值的时候,必须把第一个字节置0,即sun_path[0] = 0,下面用代码说明:

    第一种方式:

           //name the server socket 
    	server_addr.sun_family = AF_UNIX;
    	strcpy(server_addr.sun_path,SERVER_NAME);
    	server_len = sizeof(struct sockaddr_un);
    	client_len = server_len;


    第二种方式:

        //name the socket
        server_addr.sun_family = AF_UNIX;
        strcpy(server_addr.sun_path, SERVER_NAME);
        server_addr.sun_path[0]=0;
        //server_len = sizeof(server_addr);
        server_len = strlen(SERVER_NAME)  + offsetof(struct sockaddr_un, sun_path);


    其中,offsetof函数在#include <stddef.h>头文件中定义。因第二种方式的首字节置0,我们可以在命名字符串SERVER_NAME前添加一个占位字符串,例如:

    #define SERVER_NAME @socket_server
    前面的@符号就表示占位符,不算为实际名称。


    或者可以把第二种方式的实现封装成一个函数:

    int makeAddr(const char* name, struct sockaddr_un* pAddr, socklen_t* pSockLen)
    {
        int nameLen = strlen(name);
        if (nameLen >= (int) sizeof(pAddr->sun_path) -1)  /* too long? */
            return -1;
        pAddr->sun_path[0] = '\0';  /* abstract namespace */
        strcpy(pAddr->sun_path+1, name);
        pAddr->sun_family = AF_UNIX;
        *pSockLen = 1 + nameLen + offsetof(struct sockaddr_un, sun_path);
        return 0;
    }

    像下面这样使用这个函数:

    makeAddr("server_socket", &server_addr, &server_len);

    提示:客户端连接服务器的时候,必须与服务端的命名方式相同,即如果服务端是普通命名方式,客户端的地址也必须是普通命名方式;如果服务端是抽象命名方式,客户端的地址也必须是抽象命名方式。

    (3)绑定并侦听

        bind(server_sockfd, (struct sockaddr *)&server_addr, server_len);
    
        //listen the server
        listen(server_sockfd, 5);

    (4)等待客户端连接,并读写数据。

      while(1){
    		printf("server waiting...\n");
    		
    		//accept client connect
    		client_len = sizeof(client_addr);
    		client_sockfd = accept(server_sockfd,(struct sockaddr*)&client_addr, &client_len);
    	
    		//read  data from client socket
    		read(client_sockfd, &ch, 1);
    		printf("read from client %d: %c",client_sockfd,ch);
    		ch ++;
    		write(client_sockfd, &ch, 1);
    		close(client_sockfd);
    		usleep(100);//1000 miliseconds = 1 second
        }

    二 socket客户端创建流程

    (1)创建socket

    (2)命名socket

    (3)连接到服务端:

    //connect to server
    	result = connect(sockfd, (struct sockaddr*)&address, len);

    (4)与服务端进行通信

    	//communicate with server socket
    	while(1)
    	{
    		printf("set send content:");
    		scanf("%c",&ch);
    		write(sockfd, &ch, 1);
    		printf("send to server:%c \n",ch);
    		read(sockfd, &ch, 1);
    		printf("read from server: %c\n", ch);
    		
    		
    	}

    完整代码如下:

    (1)服务端server.c:

    #include<sys/types.h>
    #include<sys/socket.h>
    #include<stdio.h>
    #include<sys/un.h>
    #include<unistd.h>
    #include<stdlib.h>
    #include <stddef.h>
    
    #define SERVER_NAME "@server_socket"
    /*
     * Create a UNIX-domain socket address in the Linux "abstract namespace".
     *
     * The socket code doesn't require null termination on the filename, but
     * we do it anyway so string functions work.
     */
    int makeAddr(const char* name, struct sockaddr_un* pAddr, socklen_t* pSockLen)
    {
        int nameLen = strlen(name);
        if (nameLen >= (int) sizeof(pAddr->sun_path) -1)  /* too long? */
            return -1;
        pAddr->sun_path[0] = '\0';  /* abstract namespace */
        strcpy(pAddr->sun_path+1, name);
        pAddr->sun_family = AF_UNIX;
        *pSockLen = 1 + nameLen + offsetof(struct sockaddr_un, sun_path);
        return 0;
    }
    
    int main()
    
    {
        int server_sockfd, client_sockfd;
        socklen_t server_len, client_len;
        struct sockaddr_un server_addr;
        struct sockaddr_un client_addr;
        char ch;
        int nread;
    
        //delete the old server socket
        //unlink("server_socket");
        //create socket
        server_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
    
        //name the socket
        server_addr.sun_family = AF_UNIX;
        strcpy(server_addr.sun_path, SERVER_NAME);
        server_addr.sun_path[0]=0;
        //server_len = sizeof(server_addr);
        server_len = strlen(SERVER_NAME)  + offsetof(struct sockaddr_un, sun_path);
        //makeAddr("server_socket", &server_addr, &server_len);
        bind(server_sockfd, (struct sockaddr *)&server_addr, server_len);
    
        //listen the server
        listen(server_sockfd, 5);
        client_sockfd = -1;
        client_len = sizeof(client_addr);
        while(1){
    		printf("server waiting...\n");
    		//accept client connect
    		if(client_sockfd == -1){
    			client_sockfd = accept(server_sockfd,(struct sockaddr*)&client_addr, &client_len);
    		}
    	
    		//read  data from client socket
    		nread = read(client_sockfd, &ch, 1);
    		if(nread == 0){//client disconnected
    			printf("client %d disconnected\n",client_sockfd);
    			client_sockfd = -1;
    		}
    		else{
    			printf("read from client %d: %c\n",client_sockfd,ch);
    			ch ++;
    			write(client_sockfd, &ch, 1);
    		}
    		usleep(100);//1000 miliseconds = 1 second
        }
    
        return 0;
    
    }
    

    (2)客户端client.c

    #include<sys/types.h>
    #include<sys/socket.h>
    #include<stdio.h>
    #include<sys/un.h>
    #include<unistd.h>
    #include<stdlib.h>
    #include <stddef.h>
    #define SERVER_NAME "@server_socket"
    /*
     * Create a UNIX-domain socket address in the Linux "abstract namespace".
     *
     * The socket code doesn't require null termination on the filename, but
     * we do it anyway so string functions work.
     */
    int makeAddr(const char* name, struct sockaddr_un* pAddr, socklen_t* pSockLen)
    {
        int nameLen = strlen(name);
        if (nameLen >= (int) sizeof(pAddr->sun_path) -1)  /* too long? */
            return -1;
        pAddr->sun_path[0] = '\0';  /* abstract namespace */
        strcpy(pAddr->sun_path+1, name);
        pAddr->sun_family = AF_UNIX;
        *pSockLen = 1 + nameLen + offsetof(struct sockaddr_un, sun_path);
        return 0;
    }
    
    
    int main()
    {
    	int sockfd;
    	socklen_t len;
    	struct sockaddr_un address;
    	int result;
    	char ch = 'A';
    
    	//create socket 
    	sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
    	//name the server socket
    	//makeAddr("server_socket", &address, &len);
    	address.sun_family = AF_UNIX;
    	strcpy(address.sun_path, SERVER_NAME);
    	address.sun_path[0]=0;
    	//len = sizeof(address);
    	len =  strlen(SERVER_NAME)  + offsetof(struct sockaddr_un, sun_path);
    	//connect to server
    	result = connect(sockfd, (struct sockaddr*)&address, len);
    	if(result == -1)
    	{
    		perror("opps:client1");
    		exit(1);
    	}
    	//communicate with server socket
    	while(1)
    	{
    		printf("set send content:");
    		scanf("%c",&ch);
    		write(sockfd, &ch, 1);
    		printf("send to server:%c \n",ch);
    		read(sockfd, &ch, 1);
    		printf("read from server: %c\n", ch);
    		
    		
    	}
    	exit(0);
    
    }
    







































































    展开全文
  • Linux socket本地进程通信

    千次阅读 2017-02-17 14:58:59
    socket进程通信与网络通信使用的是统一套接口,只是地址结构与某些参数不同。 一、创建socket流程 (1)创建socket,类型为AF_LOCAL或AF_UNIX,表示用于进程通信: 创建套接字需要使用 socket 系统调用,其原型...

    使用套接字除了可以实现网络间不同主机间的通信外,还可以实现同一主机的不同进程间的通信,且建立的通信是双向的通信。socket进程通信与网络通信使用的是统一套接口,只是地址结构与某些参数不同。


    一、创建socket流程

    (1)创建socket,类型为AF_LOCAL或AF_UNIX,表示用于进程通信:

    创建套接字需要使用 socket 系统调用,其原型如下:


    int socket(int domain, int type, int protocol);


    其中,domain 参数指定协议族,对于本地套接字来说,其值须被置为 AF_UNIX 枚举值;type 参数指定套接字类型,protocol 参数指定具体协议;type 参数可被设置为 SOCK_STREAM(流式套接字)或 SOCK_DGRAM(数据报式套接字),protocol 字段应被设置为 0;其返回值为生成的套接字描述符。


    对于本地套接字来说,流式套接字(SOCK_STREAM)是一个有顺序的、可靠的双向字节流,相当于在本地进程之间建立起一条数据通道;数据报式套接字(SOCK_DGRAM)相当于单纯的发送消息,在进程通信过程中,理论上可能会有信息丢失、复制或者不按先后次序到达的情况,但由于其在本地通信,不通过外界网络,这些情况出现的概率很小


    二、命名socket

    SOCK_STREAM 式本地套接字的通信双方均需要具有本地地址,其中服务器端的本地地址需要明确指定,指定方法是使用 struct sockaddr_un 类型的变量。

    struct sockaddr_un {
        sa_family_t     sun_family;     /* AF_UNIX */
        char    sun_path[UNIX_PATH_MAX];        /* 路径名 */
    };

    这里面有一个很关键的东西,socket进程通信命名方式有两种。一是普通的命名,socket会根据此命名创建一个同名的socket文件,客户端连接的时候通过读取该socket文件连接到socket服务端。这种方式的弊端是服务端必须对socket文件的路径具备写权限,客户端必须知道socket文件路径,且必须对该路径有读权限。

    另外一种命名方式是抽象命名空间,这种方式不需要创建socket文件,只需要命名一个全局名字,即可让客户端根据此名字进行连接。后者的实现过程与前者的差别是,后者在对地址结构成员sun_path数组赋值的时候,必须把第一个字节置0,即sun_path[0] = 0,下面用代码说明:

    第一种方式:

    [cpp] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. //name the server socket   
    2.     server_addr.sun_family = AF_UNIX;  
    3.     strcpy(server_addr.sun_path,"/tmp/UNIX.domain");  
    4.     server_len = sizeof(struct sockaddr_un);  
    5.     client_len = server_len;  

    第二种方式:

    [cpp] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. #define SERVER_NAME @socket_server  
    [cpp] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. //name the socket  
    2.    server_addr.sun_family = AF_UNIX;  
    3.    strcpy(server_addr.sun_path, SERVER_NAME);  
    4.    server_addr.sun_path[0]=0;  
    5.    //server_len = sizeof(server_addr);  
    6.    server_len = strlen(SERVER_NAME)  + offsetof(struct sockaddr_un, sun_path);  



    其中,offsetof函数在#include <stddef.h>头文件中定义。因第二种方式的首字节置0,我们可以在命名字符串SERVER_NAME前添加一个占位字符串,例如:
    [cpp] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. #define SERVER_NAME @socket_server    

    前面的@符号就表示占位符,不算为实际名称。

    提示:客户端连接服务器的时候,必须与服务端的命名方式相同,即如果服务端是普通命名方式,客户端的地址也必须是普通命名方式;如果服务端是抽象命名方式,客户端的地址也必须是抽象命名方式。


    三、绑定

    SOCK_STREAM 式本地套接字的通信双方均需要具有本地地址,其中服务器端的本地地址需要明确指定,指定方法是使用 struct sockaddr_un 类型的变量,将相应字段赋值,再将其绑定在创建的服务器套接字上,绑定要使用 bind 系统调用,其原形如下:


    int bind(int socket, const struct sockaddr *address, size_t address_len);


    其中 socket表示服务器端的套接字描述符,address 表示需要绑定的本地地址,是一个 struct sockaddr_un 类型的变量,address_len 表示该本地地址的字节长度。实现服务器端地址指定功能的代码如下(假设服务器端已经通过上文所述的 socket 系统调用创建了套接字,server_sockfd 为其套接字描述符):
    struct sockaddr_un server_address;
    server_address.sun_family = AF_UNIX;
    strcpy(server_address.sun_path, "Server Socket");
    bind(server_sockfd, (struct sockaddr*)&server_address, sizeof(server_address));


    客户端的本地地址不用显式指定,只需能连接到服务器端即可,因此,客户端的 struct sockaddr_un 类型变量需要根据服务器的设置情况来设置,代码如下(假设客户端已经通过上文所述的 socket 系统调用创建了套接字,client_sockfd 为其套接字描述符):
    struct sockaddr_un client_address;
    client_address.sun_family = AF_UNIX;
    strcpy(client_address.sun_path, "Server Socket");



    四、监听
    服务器端套接字创建完毕并赋予本地地址值(名称,本例中为Server Socket)后,需要进行监听,等待客户端连接并处理请求,监听使用 listen 系统调用,接受客户端连接使用accept系统调用,它们的原形如下:
    int listen(int socket, int backlog);
    int accept(int socket, struct sockaddr *address, size_t *address_len);
    其中 socket 表示服务器端的套接字描述符;backlog 表示排队连接队列的长度(若有多个客户端同时连接,则需要进行排队);address 表示当前连接客户端的本地地址,该参数为输出参数,是客户端传递过来的关于自身的信息;address_len 表示当前连接客户端本地地址的字节长度,这个参数既是输入参数,又是输出参数。实现监听、接受和处理的代码如下:
    #define MAX_CONNECTION_NUMBER 10
    int server_client_length, server_client_sockfd;
    struct sockaddr_un server_client_address;
    listen(server_sockfd, MAX_CONNECTION_NUMBER);
    while(1)
    {
        // ...... (some process code)
        server_client_length = sizeof(server_client_address);
        server_client_sockfd = accept(server_sockfd, (struct sockaddr*)&server_client_address, &server_client_length);
        // ...... (some process code)
    }
    这里使用死循环的原因是服务器是一个不断提供服务的实体,它需要不间断的进行监听、接受并处理连接,本例中,每个连接只能进行串行处理,即一个连接处理完后,才能进行后续连接的处理。如果想要多个连接并发处理,则需要创建线程,将每个连接交给相应的线程并发处理。
    客户端套接字创建完毕并赋予本地地址值后,需要连接到服务器端进行通信,让服务器端为其提供处理服务。对于 SOCK_STREAM 类型的流式套接字,需要客户端与服务器之间进行连接方可使用。连接要使用 connect 系统调用,其原形为


    int connect(int socket, const struct sockaddr *address, size_t address_len);


    其中socket为客户端的套接字描述符,address表示当前客户端的本地地址,是一个 struct sockaddr_un 类型的变量,address_len 表示本地地址的字节长度。实现连接的代码如下:
    connect(client_sockfd, (struct sockaddr*)&client_address, sizeof(client_address));
    无论客户端还是服务器,都要和对方进行数据上的交互,这种交互也正是我们进程通信的主题。一个进程扮演客户端的角色,另外一个进程扮演服务器的角色,两个进程之间相互发送接收数据,这就是基于本地套接字的进程通信。发送和接收数据要使用 write 和 read 系统调用,它们的原形为:
    int read(int socket, char *buffer, size_t len);
    int write(int socket, char *buffer, size_t len);
    其中 socket 为套接字描述符;len 为需要发送或需要接收的数据长度;对于 read 系统调用,buffer 是用来存放接收数据的缓冲区,即接收来的数据存入其中,是一个输出参数;对于 write 系统调用,buffer 用来存放需要发送出去的数据,即 buffer 内的数据被发送出去,是一个输入参数;返回值为已经发送或接收的数据长度。例如客户端要发送一个 "Hello" 字符串给服务器,则代码如下:
    char buffer[10] = "Hello";
    write(client_sockfd, buffer, strlen(buffer));
    交互完成后,需要将连接断开以节省资源,使用close系统调用,其原形为:
    int close(int socket);
    不多说了,直接使用,大家一定都会,呵呵!
    上面所述的每个系统调用都有 -1 返回值,在调用不成功时,它们均会返回 -1,这个特性可以使得我们用 if - else 或异常处理语句来处理错误,为我们提供了很大的方便。
    SOCK_DGRAM 数据报式本地套接字的应用场合很少,因为流式套接字在本地的连接时间可以忽略,所以效率并没有提高,而且发送接收都需要携带对方的本地地址,因此很少甚至几乎不使用。
    与本地套接字相对应的是网络套接字,可以用于在网络上传送数据,换言之,可实现不同机器上的进程通信过程。在 TCP/IP 协议中,IP 地址的首字节为 127 即代表本地,因此本地套接字通信可以使用 IP 地址为 127.x.x.x 的网络套接字来实现。


    展开全文
  • linux进程通信 socket编程

    测试了利用socket传输一张图片,在同一台机器上两个进程通信

    send.cpp 

    主要是socket用来connect一个服务器

    #include <opencv2/opencv.hpp>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <netinet/tcp.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <errno.h>
    #include <fstream>
    #include <iostream>
    #include <sstream>
    
    using namespace std;
    using namespace cv;
    
    int main(int argc, char *argv[])  
    {  
        int my_socked, portno, n;
        
        struct hostent *server;
    
        portno = atoi(argv[1]);
    
        my_socked = socket(AF_INET, SOCK_STREAM, 0);
        if (my_socked < 0)
            cout << "ERROR opening socket" << endl;
    
        //NETWORK
        struct sockaddr_in serv_addr;
        bzero((char *) &serv_addr, sizeof(serv_addr));
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_port = htons(portno);
        serv_addr.sin_addr.s_addr = inet_addr(argv[2]);//127.0.0.1
    
    
        // re-use already bound address/port (if possible)
        int optval = 1;
        if (setsockopt(my_socked, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(int)) < 0)
            cout << "Cannot set SO_REUSEADDR option on listen socket " << endl;
        // set TCP_NODELAY for sure
        optval = 1;
        if (setsockopt(my_socked, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(int)) < 0)
            cout << "  Cannot set TCP_NODELAY option on listen socket" << endl;
    
        if (connect(my_socked, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
            cout << "ERROR connecting" << endl;
    
        Mat img=imread("5.png",1);
        //frame = (frame.reshape(0,1)); // to make it continuous
    
        int imgSize =3*img.rows*img.cols;//640*480*3
    
        // Send data here
        int bytes = send(my_socked, img.data, imgSize, 0);
    
        close(my_socked);
    }  

    read.cpp

    流程就是建立socket,然后bind一个地址,然后设置监听,然后另外一个socket用来accept。为啥过程是这样不是很懂

    #include <opencv2/opencv.hpp>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/tcp.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <errno.h>
    #include <fstream>
    #include <iostream>
    #include <sstream>
    
    using namespace std;
    using namespace cv;
    
    int main(int argc, char *argv[]){
        
       
        if (argc < 4) {
            cout << "ERROR, no port provided" << endl;
            return -1;
        }
        
    
        int sockfd, portno;
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd < 0)
            cout << "ERROR opening socket" << endl;
    
        int reuse;
        if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(int)) == -1){
         printf("Reuse port Error : %s\n", strerror(errno));
        }
        int optval = 1;
        if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(int)) < 0)
          cout << "  Cannot set TCP_NODELAY option on listen socket" << endl;
    
    
    
        struct sockaddr_in serv_addr, cli_addr;
        bzero((char *) &serv_addr, sizeof(serv_addr));
    
        portno = atoi(argv[1]);
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_addr.s_addr = INADDR_ANY;
        serv_addr.sin_port = htons(portno);
    
        if (bind(sockfd, (struct sockaddr *) &serv_addr,
                 sizeof(serv_addr)) < 0)
            cout << "ERROR on binding" << endl;
    
        listen(sockfd,5);
    
    
        socklen_t clilen;
        clilen = sizeof(cli_addr);
    
        int newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr,&clilen);
        if (newsockfd < 0)
            cout << "ERROR on accept" << endl;
    
    
    
        //SETUP OUTPUT
        namedWindow( "Server", CV_WINDOW_NORMAL );// Create a window for display.
    
        int bytes = 0, bytecount = 0;
        Mat  img;
        
        int width = atoi(argv[2]);
        int height = atoi(argv[3]);
        int imgSize = 3*height*width;//921600;
        uchar sockData[imgSize];
        while(1){
            img = Mat::zeros( height,width, CV_8UC3);
    
            // for (int i = 0; i < imgSize; i += bytes) {
       //           if ((bytes = recv(newsockfd, sockData +i, imgSize  - i, 0)) == -1) {
       //               cout<<"recv failed"<<endl;
       //               return -1;
       //            }
        //   }
                //MSG_WAITALL
            bytes = 0;
            bytecount = 0;
            for (int i = 0; i < imgSize; i += bytes) {
                if ((bytes = recv(newsockfd, (sockData + i), imgSize  - i, MSG_WAITALL)) == -1) {
                    cout << "recv failed" << endl;
                    return -1;
                }
                if (bytes == 0)
                    bytecount++;
                if ( bytecount == 20) {
                    //cleanup();
                    cout<<"cleanup"<<endl;
                    return 0;
                }
            }
            int ptr=0;
            for (int i = 0;  i < img.rows; i++) {
                for (int j = 0; j < img.cols; j++) {                                     
                     img.at<cv::Vec3b>(i,j) = cv::Vec3b(sockData[ptr+ 0],sockData[ptr+1],sockData[ptr+2]);
                     ptr=ptr+3;
                 }
            }
            imshow( "Server", img );
    
            waitKey(0);
            // if (waitKey(0) == 27)
            // {
            //     break;
            // }
    
        }
    
    
        close(newsockfd);
        close(sockfd);
        return 0;
    
    }



    展开全文
  • 基于socket文件的进程通信:  Socket文件进程通信方式,比较重要,原因:网络业采用这种通信模型。  两种模型:  对等模型  C/S模型(服务器客户端模型)   1. 对等模型: 1. 建立socket #include ...

    基于socket文件的进程通信:

         Socket文件进程通信方式,比较重要,原因:网络业采用这种通信模型。

         两种模型:

                  对等模型

                  C/S模型(服务器客户端模型)

     

    1.      对等模型:

    1.      建立socket

    #include<sys/socket.h>

        1.建立socket:socket

                                            intsocket(

    int domain,//地址族的类型AF_UNIX (绑定在本地) AF_INET(绑定在网卡)

                int type,//支持的数据格式:流SOCK_STREAM/报文SOCK_DGRAM

                                       int protocol);//支持的协议,建议为0

                                            返回值:

                                                          成功返回文件描述符号。

                                                          失败返回-1;

    2.绑定在地址上(文件目录地址)URL(Universe ResourceLocation)

                                            协议://路径/文件名

                                            file:///usr/bin/ls      普通文件

                                            http://192.168.0.72/index.php

                                     structsockaddr;  地址结构体

     

                       #include<linux/un.h>

                                            structsockaddr_un;   un=unix(绑定unix本地)

                           struct sockaddr_un{

                                  sa_family_t   sun_family; /*AF_UNIX*/

                                  char sun_path[UNIX_PATH_MAX];

                           };

     

                                            structsockaddr_in;   in=internet(绑定网卡)

                                            intbind(int fd,//socket描述符号

                                                          structsockaddr*addr,//绑定地址

                                                          socklen_tsize);//地址长度

                           返回值:0成功,-1失败

                                                         

                                           

         3.接收数据

                read/recv/recvfrom

         4.关闭socket

     

     连接方:         

         1.建立socket:socket

         2.连接到目标:connect(可选)      

     int connect(int sockfd , const struct sockaddr * serv_addr , socklen_taddrlen);

     参数:和bind一样

      返回值:0成功,-1失败   

         3.发送数据:write/send/sendto

         4.关闭close

     

     

    案例:

    socketA.c

     

    #include<sys/socket.h>

    #include<stdio.h>

    #include<stdlib.h>

    #include<string.h>

    #include<unistd.h>

    #include<linux/un.h>

     

    void   main()

    {

               int fd;

               int r;

               char buf[];

               //1.建立socket

                fd=socket(AF_UNIX , SOCK_DGRAM , 0);  //AF_FILE 等同//AF_UNIX

                 if(fd == -1)  printf(“socket error:%m\n”) , exit(-1);

                 //2.构造本地文件地址

                 struct   sockaddr_un addr={0};

                 addr.sun_family=AF_UNIX; //必须跟socket的地址族一致

                 memcpy(addr.sun_path , “my.sock”,strlen(“my.sock”));

                 //3.把socket绑定在地址上

                 r=bind(fd , (struct  sockaddr *)&addr , sizeof(addr));

                 if(r== -1) printf(“bind error:%m\n”), exit(-1);

                 //4.接收数据

                 bzero(buf , sizeof(buf));

                 r=read(fd , buf , sizeof(buf));

                 buf[r]=0;

                 printf(“%s\n”,buf);

                 //5.关闭

                 close(fd);

                 //6.删除socket文件

                 unlink(“my.sock”);

    //socket文件不会自动删除,需要在程序结尾去删除该文件,否则,再次运行//A程序出错

              

    }

     

     

     

    SocketB.c

    #include<stdio.h>

    #include<stdlib.h>

    #include<sys/socket.h>

    #include<linux/un.h>

    #include<string.h>

    #include<unistd.h>

     

    void   main()

    {

           int  fd;

           struct  sockaddr_un  addr={0};

          //1.建立socket

          fd=socket(AF_UNIX , SOCK_DGRAM , 0);

          //2.连接到指定的地址

          addr.sun_family=AF_UNIX;

          memcpy(addr.sun_path, “my.sock” ,strlen(“my.sock”));

          r=connect(fd , (sockaddr *)&addr ,sizeof(addr));

          //3.发送数据

          write(fd, “hello !”,strlen(“hello!”));

          //4.关闭

          close(fd);

    }

     

     

    展开全文
  • Linux socket 本地进程通信

    千次阅读 2016-02-26 01:00:42
    socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。Socket就是该模式的一个实现, socket即是一种特殊的文件,一些socket...
  • Linux中查看socket进程状态

    千次阅读 2016-03-16 19:45:48
    Linux中查看socket进程状态 Linux中查看socket状态: cat /proc/net/sockstat #(这个是ipv4的) sockets: used 137 TCP: inuse 49 orphan 0 tw 3272 alloc 52 mem 46UDP: inuse 1 mem 0RAW: inuse 0 ...
  • Linux下的socket简单通信

    千次阅读 2021-03-11 09:52:45
    回送地址(127.x.x.x)是本机回送地址(Loopback Address),即主机IP堆栈内部的IP地址,主要用于网络软件测试以及本地机进程通信,无论什么程序,一旦使用回送地址发送数据,协议软件立即返回,不进行任何网络...
  • linux 进程间使用unix socket通信

    千次阅读 2017-08-27 17:45:15
    前言:前些天实现了unix socket通信想完完全全自己写一篇博客记录下来,但写的时候发现对于socket知识的理解还有所欠缺,故引用其他博客写的比较好的部分综合一下,这样让大家更容易理解。 一、Unix socket...
  • socket进程通信与网络通信使用的是统一套接口,只是地址结构与某些参数不同。 其主要流程如下: 代码实现如下: 客户端: //client #include #include #include #include #include #define UN
  • Linux进程间套接字(Socket通信

    千次阅读 2015-11-06 00:13:24
    套接字(Socket通信原理套接字通信允许互联的位于不同计算机上的进程之间实现通信功能。套接字的属性套接字的特性由3个属性确定,它们分别是:域、类型和协议。套接字的域它指定套接字通信中使用的网络介质,最...
  • 目录 程序流程 程序实例 运行结果 例主要是让服务器能够...3. 在子进程中进行客户端与服务端的数据通信; 4. 在父进程中定义一个消息处理程序,用来等待子进程结束,从而防止僵尸进程的产生。 程序实例 #i...
  • 这会是一系列文章,讲解的内容也很简单,文章的目的是让自己的知识固话和文档化,以...之前有讲到共享内存是最高效的 IPC 方式,但是在 linux 环境下,应用最广泛的可能是 Socket。 什么是 Unix Domain Socket ? S...
  • Linux 进程通信 socket

    千次阅读 2013-06-03 15:10:59
    一个linux UDP网络通讯的例子源代码(server、client方式) 服务器端代码 #include #include #include #include #include #include #include #include
  • 这会是一系列文章,讲解的内容也很简单,文章的目的是让自己的知识固话和文档化,以...之前有讲到共享内存是最高效的 IPC 方式,但是在 linux 环境下,应用最广泛的可能是 Socket。 什么是 Unix Domain Socket ? S...
  • Socket进程通信

    千次阅读 2016-08-29 20:51:26
    当你用QQ聊天时,QQ进程怎么与服务器或你好友所在的QQ进程通信?这些都得靠socket?那什么是socketsocket的类型有哪些?还有socket的基本函数,这些都是本文想介绍的。本文的主要内容如下: 1、网络中进程之间...
  • linux 本地socket通信

    千次阅读 2016-08-10 11:05:46
    linux 本地socket通信linux中的进程通信,不仅仅有消息队列,共享内存,管道,等! 本地socket也是不错的机制,效率只比消息队列低一点。#include #include #include #include #include #include #inc
  • 结论:不走网卡,不走物理设备,但是走虚拟设备,loopback device环回. 最简单的办法,拔掉网线,自己测试一...本机的报文的路径是这样的: 应用层-> socket接口 -> 传输层(tcp/udp报文) -> 网络层 -> back to
  • #Linux#进程通信# 套接字(socket)

    万次阅读 2019-12-27 14:04:36
    套接字(socket)是一种通信机制,凭借这种机制,客户/服务器 (即要进行通信进程)系统的开发工作既可以在本地单机上进行, 也可以跨网络进行。也就是说它可以让不在同一台计算机但通过网 络连接计算机上的进程进行...
  • 套接口(Socket)为目前Linux上最为广泛使用的一种的进程通信机制,与其他的Linux通信机制不同之处在于除了它可用于单机内的进程通信以外,还可用于不同机器之间的进程通信。但是由于Socket本身不支持同时等待...
  • Linux进程通信基本概念 从原理上来看,进程通信的关键技术就是在进程间建立某种共享区,利用进程都可以访问共享区的特点来建立一些通信通道。如下图所示: 其实,以前设计程序时使用的全局变量,就是一种可以在...
  • Linuxsocket编程实现客户服务器通信的例子经典的在同一台主机上两个进程或线程之间的通信通过以下三种方法 管道通信(Pipes) 消息队列(Message queues) 共享内存通信(Shared memory) 这里有许多其他的方法...
  • unix domain socket 进程通信简析

    千次阅读 2013-09-09 21:16:35
    Linux系统有多种进程通信方式,如信号、消息队列、管道等,socket是其中一种,socket使用unix domain 模式进行进程通信 //服务端代码 #include #include #include #include #include #define UNIX_SERV...
  • UNIX_SOCKET 进程通信

    千次阅读 2017-03-30 10:29:22
    使用socket实现进程通信:(UNIX domain中面向连接通信)  使用套接字除了可以实现网络间不同主机间的通信外,还可以实现同一主机的不同进程间的通信,且建立的通信是双向的通信。 man unix内容如下: NAME( ...
  • linux下使用socket中的select完成单线程单进程多用户之间通信 (2011-12-16 19:34:14) 转载▼ 标签: 杂谈   使用select函数可以以非阻塞的方式和多个socket通信。程序只是演示select...
  • Linux进程通信

    千次阅读 2019-04-21 08:00:23
    进程通信11.1进程通信介绍11.2Linux内核提供的进程通信机制11.3管道11.4SystemV IPC介绍 11.进程通信 11.1进程通信介绍 进程通信(IPC)指的是2个任意进程之间的通信进程用户空间是相互独立的,一般...
  • Socket进程通信原理

    千次阅读 2013-08-29 14:30:32
    暂时总结了Client和Server端通信的代码实现模型。主要是中间通过一个通道去传信息,而这个通道就是一个特殊的文件(Linux中一切对象皆文件)。 这是通道建立的示意图: 1.服务端先绑定 2.client端connect,会触发...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 82,243
精华内容 32,897
关键字:

linux本机socket进程通信

linux 订阅