进程间通信-本地套接字

UNIX域套接字
UNIX域套接字用于同一台计算机上运行的进程之间的通信。他的执行效率更高,仅仅是复制数据,并不执行协议处理,不需要添加和删除网络报头,不需要计算校验和等 只支持流式和数据报两种接口,服务是可靠的,不会丢失报文也不会出错。

服务端的创建流程:
1、创建本地套接字
2、绑定本地套接字文件(选定文件位置和名称)
3、监听
4、消息收发

客户端的创建流程:
1、创建本地套接字
2、绑定本地套接字文件(选定文件位置和名称)
3、链接
4、消息收发

(1)创建套接字

int socket(int domain,int type,int protocol);//创建一个套接字
//domain(域):指定协议族,对于本地套接字来说,填 AF_LOCAL 或 AF_UNIX 即可
//type:确定套接字类型,如SOCKET_STREAM(流式套接字),SOCKET_SEQPACKET(报文传递)
//protocol:如果第二个参数 type 不是原始套接字, protocol 一般填 0 就可以了

(2)绑定套接字

unlink(path)//确保之前path文件不存在,bind会创建该文件。。。如果存在这个文件不unlink,bind会失败
int bind(int socket, const struct sockaddr *address, size_t address_len);
//socket:服务端套接字描述符
//address:需要绑定的服务端本地地址
//address_len:本地地址的字节长度

当不再需要这个 Unix 域套接字时,应删除路径名对应的文件。如果是抽象路径名,就不需要在使用完本地套接字后手动删除对应的套接字文件,因为当本地套接字被关闭之后,内核会自动删除这个抽象名。

int unlink(const char *pathname);
int remove(const char *pathname);

.本地套接字的地址结构体 sockaddr_un 的后缀是 _un,表示 Unix,而不是原来的 sockaddr_in(Internet)。

网络套接字地址结构:

struct sockaddr_in {
    __kernel_sa_family_t sin_family;         /* Address family */        地址结构类型
    __be16 sin_port;                         /* Port number */        端口号
    struct in_addr sin_addr;                 /* Internet address */ IP地址
};

本地套接字地址结构:

struct sockaddr_un {
    __kernel_sa_family_t sun_family;       /* AF_UNIX */           地址结构类型
    char sun_path[UNIX_PATH_MAX];         /* pathname */          socket文件名(含路径)
    //Unix 本地套接字关联的这个路径名应该是一个绝对路径名,而不是一个相对路径名

这个路径名,其实还要分为两种,一种是我们上面所提到的普通路径名,另一种是抽象路径名。普通路径名是一个正常的字符串,也就是说,sun_path 字段是以空字符(’\0’)结尾的。而抽象路径名,sun_path 字段的第一个字节需要设置成 NULL(’\0’),所以在计算抽象路径名的长度的时候就要特别小心了,否则在解析抽象路径名时就有可能出现异常情况,因为抽象路径名不是像解析普通路径名那样,解析到第一个 NULL 就可以停止了。 使用抽象路径名的好处是,因为不会再在文件系统中创建文件了,所以对于抽象路径名来说,就不需要担心与文件系统中已存在的文件产生名字冲突的问题了,也不需要在使用完套接字之后删除附带产生的这个文件了,当套接字被关闭之后会自动删除这个抽象名。

(3)监听
服务器端套接字创建完毕并赋予本地地址值后,需要进行监听,等待客户端连接并处理请求,监听使用 listen 系统调用,接受客户端连接使用accept系统调用,它们的原形如下:

int listen(int socket, int backlog);
int accept(int socket, struct sockaddr *address, size_t *address_len);
参数
socket:表示服务器端的套接字描述符;
backlog 表示排队连接队列的长度(若有多个客户端同时连接,则需要进行排队);
address 表示当前连接客户端的本地地址,该参数为输出参数,是客户端传递过来的关于自身的信息;
address_len 表示当前连接客户端本地地址的字节长度,这个参数既是输入参数,又是输出参数。实现监听、接受和处理。

(4)连接
客户端需要socket系统调用connect()连接到服务端,其函数原型如下:

int connect(int socket, const struct sockaddr *address, size_t address_len);
参数
socket:客户端的套接字描述符
address:当前客户端的本地地址,是一个 struct sockaddr_un 类型的变量
address_len:表示本地地址的字节长度

(5)读写

ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);

read实际只是将内核的接收缓冲区里的数据复制到buf中,当内核的接收缓冲区为空时,read就会阻塞(阻塞模式下),当内核的接收缓冲区有数据时,read就会去读,当read成功时,read返回实际所读的字节数。若返回的值时0,说明对方的socket已经关闭。若返回的值为负数,说明链接异常。

write也是将buf中的数据复制到内核的发送缓冲区,至于数据之间的真正通信,是由内部协议去处理的。当内核的发送缓冲区写满时,write就会被阻塞,当wite成功时,wite返回实际所写的字节数。若对方的socket句柄已关闭,执行写操作,就会产生了SIGPIPE信号,导致进程退出。若返回的值为负数,说明链接异常。

无论时write还是read,如果返回的值为负数,并且错误码errno为EINT或者EAGAIN时,socket的连接是正常的,并不影响read、write操作,下次可以循环去read或者write即可。其中EINTR指操作被中斷喚醒,需要重新讀/寫,EAGAIN是在非阻塞操作中,不断去读,就会有EAGAIN提醒,说明没有数据可读。

测试实例说明(两进程的本地套接字通信)
1、建立两个进程,一个为客户端、一个为服务端。服务端负责发送命令,客户端负责接收命令并执行命令。
2、客户端和服务端进程任一个进程关闭,都不会影响对方挂掉,重新运行后能正常建立链接,正常通信。
3、是进程间命令交互和配置比较好的架构设计。

测试例子
socket_commom.c

#ifndef __SOCKET_COMMOM_C__
#define __SOCKET_COMMOM_C__

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>
#include <sys/un.h>
#include <fcntl.h>
#include <sys/types.h>

#include "socket_commom.h"

#define  MAX_SEND_BUF_LEN 1400
#define SOCKET_MSGIC (0xaabbcc)

typedef struct __MSG_HEAD_T__
{
	unsigned int u32Magic;	//socket magic
	unsigned int u32Len;		//msg length
}MSG_HEAD_T;

int Fun_Socket_send_noblock(int nSocket, char *pBuf, int nBufLen, struct timeval *pTimeOut)
{
	int nLen = 0, nWriteLen = 0, nSendLen = 0;
	fd_set writefds;
	int ret = 0;
	struct timeval stTimeout;
	if(pTimeOut == NULL)
	{
		stTimeout.tv_sec = 2;
		stTimeout.tv_usec = 0;
	}else
	{
		stTimeout.tv_sec = pTimeOut->tv_sec;
		stTimeout.tv_usec = pTimeOut->tv_usec;
	}
	if(nSocket < 0 || pBuf == NULL || nBufLen <= 0)
	{
		printf("socket: %d, pBuf = %p, nBufLen:%d\n", nSocket, pBuf, nBufLen);
		return -1;
	}
	int nMaxfd = nSocket + 1;
	while(nLen < nBufLen)
	{
		FD_ZERO(&writefds);
		FD_SET(nSocket, &writefds);
		
		ret = select(nMaxfd, NULL, &writefds, NULL, &stTimeout);
		if(ret < 0)
		{
			printf("select err!\n");
			return -1;
		}else if(ret == 0)
		{
			return nLen;
		}else
		{
			if(FD_ISSET(nSocket, &writefds))
			{
				if(nBufLen - nLen > MAX_SEND_BUF_LEN)
				{
					nSendLen = MAX_SEND_BUF_LEN;
				}else
				{
					nSendLen = nBufLen - nLen;
				}
				nWriteLen = send(nSocket, pBuf + nLen, nSendLen, 0);
				if(nWriteLen < 0)
				{
					if(errno == EINTR)
					{
						usleep(1000);
						printf("send EINTR!\n");
						continue;
					}
					if(errno == EAGAIN)
					{
						usleep(1000);
						printf("send EAGAIN!\n");
						continue;
					}
					if(errno == EWOULDBLOCK)
					{
						usleep(1000);
						printf("send EWOULDBLOCK!\n");
						continue;
					}
					return -1;
				}
				nLen += nWriteLen;
			}
		}		
	}
	return nLen;
}

int socket_recv_noblock(int nSocket, char *pBuf, int nBufLen, struct timeval *pTimeOut)
{
	int nLen = 0, nReadLen = 0, nRecvLen = 0;
	fd_set readfds;
	int ret = 0;
	struct timeval stTimeout;
	if(pTimeOut == NULL)
	{
		stTimeout.tv_sec = 6;
		stTimeout.tv_usec = 0;
	}else
	{
		stTimeout.tv_sec = pTimeOut->tv_sec;
		stTimeout.tv_usec = pTimeOut->tv_usec;
	}
	if(nSocket < 0 || pBuf == NULL || nBufLen <= 0)
	{
		printf("socket: %d, pBuf = %p, nBufLen:%d\n", nSocket, pBuf, nBufLen);
		return -1;
	}
	int nMaxfd = nSocket + 1;
	nRecvLen = nBufLen;
	while(nLen < nBufLen)
	{
		FD_ZERO(&readfds);
		FD_SET(nSocket, &readfds);
		
		ret = select(nMaxfd, &readfds, NULL, NULL, &stTimeout);
		if(ret < 0)
		{
			printf("select err!\n");
			return -1;
		}else if(ret == 0)
		{
			return nLen;
		}else
		{
			if(FD_ISSET(nSocket, &readfds))
			{
				nRecvLen = nBufLen - nLen;
				nReadLen = recv(nSocket, pBuf + nLen, nRecvLen, 0);
				if(nReadLen < 0)
				{
					if(errno == EINTR)
					{
						usleep(1000);
						printf("recv EINTR!\n");
						continue;
					}
					if(errno == EAGAIN)
					{
						usleep(1000);
						printf("recv EAGAIN!\n");
						continue;
					}
					if(errno == EWOULDBLOCK)
					{
						usleep(1000);
						printf("recv EWOULDBLOCK!\n");
						continue;
					}
					return -1;
				}else if(nReadLen == 0)
				{
					printf("close by client\n");
					return -1;
				}
				nLen += nReadLen;
			}
		}		
	}
	return nLen;
}

int socket_send_block(int nSocket, char *pBuf, int nBufLen)
{
	int nLen = 0, nWriteLen = 0, nSendLen = 0;
//	int ret = 0;
	if(nSocket < 0 || pBuf == NULL || nBufLen <= 0)
	{
		printf("socket: %d, pBuf = %p, nBufLen:%d\n", nSocket, pBuf, nBufLen);
		return -1;
	}
	while(nLen < nBufLen)
	{
		if(nBufLen - nLen > MAX_SEND_BUF_LEN)
		{
			nSendLen = MAX_SEND_BUF_LEN;
		}else
		{
			nSendLen = nBufLen - nLen;
		}
		nWriteLen = send(nSocket, pBuf + nLen, nSendLen, 0);
		if(nWriteLen < 0)
		{
			if(errno == EINTR)
			{
				usleep(1000);
				printf("send EINTR!\n");
				continue;
			}
			if(errno == EAGAIN)
			{
				usleep(1000);
				printf("send EAGAIN!\n");
				continue;
			}
			if(errno == EWOULDBLOCK)
			{
				usleep(1000);
				printf("send EWOULDBLOCK!\n");
				continue;
			}
			return -1;
		}
		nLen += nWriteLen;
	}
	return nLen;
}

int socket_recv_block(int nSocket, char *pBuf, int nBufLen)
{
	int nLen = 0, nReadLen = 0, nRecvLen = 0;
//	int ret = 0;
	if(nSocket < 0 || pBuf == NULL || nBufLen <= 0)
	{
		printf("socket: %d, pBuf = %p, nBufLen:%d\n", nSocket, pBuf, nBufLen);
		return -1;
	}
	nRecvLen = nBufLen;
	while(nLen < nBufLen)
	{
		nRecvLen = nBufLen - nLen;
		nReadLen = recv(nSocket, pBuf + nLen, nRecvLen, 0);
		if(nReadLen < 0)
		{
			if(errno == EINTR)
			{
				usleep(1000);
				printf("recv EINTR!\n");
				continue;
			}
			if(errno == EAGAIN)
			{
				usleep(1000);
				printf("recv EAGAIN!\n");
				continue;
			}
			if(errno == EWOULDBLOCK)
			{
				usleep(1000);
				printf("recv EWOULDBLOCK!\n");
				continue;
			}
			return -1;
		}else if(nReadLen == 0)
		{
			printf("close by client\n");
			return -1;
		}
		nLen += nReadLen;
	}
	return nLen;
}

int Fun_Socket_send(int nSocket, char *pBuf, int nBufLen, struct timeval *pTimeOut)
{
	if(nSocket < 0 || pBuf == NULL || nBufLen <= 0)
	{
		printf("socket: %d, pBuf = %p, nBufLen:%d\n", nSocket, pBuf, nBufLen);
		return -1;
	}
	int ret = 0;
	MSG_HEAD_T stMsgHead = {0};
	stMsgHead.u32Len = nBufLen;
	stMsgHead.u32Magic = SOCKET_MSGIC;
	if((ret = socket_send_block(nSocket, (char *)&stMsgHead, sizeof(stMsgHead))) <= 0)
	{
		printf("ret is %d, send stMsgHead err!\n", ret);
		return -1;
	}
	return socket_send_block(nSocket, pBuf, nBufLen);
}

int Fun_Socket_recv(int nSocket, char *pBuf, int nBufLen, struct timeval *pTimeOut)
{
	if(nSocket < 0 || pBuf == NULL || nBufLen <= 0)
	{
		printf("socket: %d, pBuf = %p, nBufLen:%d\n", nSocket, pBuf, nBufLen);
		return -1;
	}
	MSG_HEAD_T stMsgHead = {0};
	int ret = 0;
	if((ret = socket_recv_noblock(nSocket, (char *)&stMsgHead, sizeof(stMsgHead),pTimeOut)) < 0)
	{
		printf("socket_recv_noblock err!\n");
		return -1;
	}
	if(ret == 0)
	{
		printf("Fun_Socket_recv fail!\n");
		return 0;
	}
	if(stMsgHead.u32Magic != SOCKET_MSGIC)
	{
		printf(">>>>>the u32Magic %x err!\n", stMsgHead.u32Magic);
		return -1;
	}
	if(stMsgHead.u32Len > nBufLen)
	{
		printf(">>>>the stMsgHead.u32Len is %u, the nBufLen is %d", stMsgHead.u32Len,  nBufLen);
		return -1;
	}
	return socket_recv_noblock(nSocket, pBuf, stMsgHead.u32Len,pTimeOut);
}


int Fun_Socket_OpenSession(SESSION_TYPE_E type,char *name,char *cli_path)
{
	int fd = -1;
    struct sockaddr_un serv_addr, cli_addr;
	int len = 0;
	char paths[64];

    if(name == NULL || cli_path == NULL)
    {
    	printf(">>>>>Fun_Socket_OpenSession param err!\n");
        return -1;    
    }

	memset (&serv_addr, 0, sizeof(serv_addr));
	serv_addr.sun_family = AF_UNIX;
	strcpy (serv_addr.sun_path, name);
	
	if(access(cli_path,F_OK)!=0)
	{
		sprintf(paths,"mkdir %s\n",cli_path);
		system(paths);
	}

	/* create a Unix domain stream socket */
	if ((fd = socket (AF_LOCAL, SOCK_STREAM, 0)) < 0)
	{
		perror("Fun_Socket_OpenSession socket ");
        return -1;
	}

	if(SESSION_CLIENT == type)
	{
		memset (&cli_addr, 0, sizeof(cli_addr));
		cli_addr.sun_family = AF_UNIX;
		sprintf(cli_addr.sun_path, "%scli%05d", cli_path, getpid());
		len = sizeof (cli_addr.sun_family) + strlen (cli_addr.sun_path);

		unlink (cli_addr.sun_path);//确保之前path文件不存在,bind会创建该文件。。。如果存在这个文件不unlink,bind会失败

		if(-1 == bind(fd,  (struct sockaddr *)&cli_addr, len))
		{
			perror("Fun_Socket_OpenSession client bind ");
			close(fd);
			return -1;
		}

		if (chmod(cli_addr.sun_path, 0666) < 0)
		{
			perror("Fun_Socket_OpenSession client chmod ");
			unlink (cli_addr.sun_path);
			close(fd);
			return -1;
		}
        len = sizeof(serv_addr.sun_family) + strlen (serv_addr.sun_path);
		if(-1 == connect(fd,  (struct sockaddr *)&serv_addr, len))
		{
			perror("Fun_Socket_OpenSession client connect ");
			unlink (cli_addr.sun_path);
			close(fd);
			return -1;
		}
	}
	else if(SESSION_SERVER == type)
	{

		unlink (serv_addr.sun_path);//确保之前path文件不存在,bind会创建该文件。。。如果存在这个文件不unlink,bind会失败
        len = sizeof(serv_addr.sun_family) + strlen (serv_addr.sun_path);
		if(bind(fd, (struct sockaddr *) &serv_addr, len) < 0 )
		{
			perror("Fun_Socket_OpenSession server bind");
			close(fd);
			return -1;
		}

    	if(chmod(name, 0666) < 0)
		{
			perror("Fun_Socket_OpenSession server chmod");
			unlink (serv_addr.sun_path);
			close(fd);
        	return -1;
		}

		if(listen(fd, 5) < 0)
    	{
    		perror("Fun_Socket_OpenSession server listen");
			unlink (serv_addr.sun_path);
			close(fd);
			return -1;
		}
	}

	return fd;
}


void Fun_Socket_CloseSessionToServer(int nSocket)
{
    if(nSocket > 0)
    {
        close(nSocket);
    }

    return;
}

int Fun_Socket_WaitForClient(int nSocket)
{
    return accept(nSocket, NULL, NULL);
}

#endif

socket_commom.h

#ifndef __SOCKET_COMMOM_H__
#define __SOCKET_COMMOM_H__

#ifndef __SOCKET_COMMOM_C__
#define _SOCKET_FUN 
#else
#define _SOCKET_FUN extern
#endif

#include <sys/time.h>

typedef unsigned char           UINT8;
typedef unsigned short          UINT16;
typedef unsigned int            UINT32;
typedef unsigned long long      UINT64;
//typedef unsigned float            UFLOAT32;

typedef signed char             SINT8;
typedef signed short            SINT16;
typedef signed int              SINT32;
typedef signed long long        SINT64;
typedef float                   SFLOAT32;
//typedef signed float            SFLOAT32;

typedef int BOOL;
#ifndef TRUE
#define TRUE 1
#endif

#ifndef FALSE
#define FALSE 0
#endif


#ifndef NULL
    #define NULL    0L
#endif


#define SUCCESS            (0)
#define FAILURE            (-1)

typedef enum
{
	SESSION_SERVER = 0,
	SESSION_CLIENT = 1,
}SESSION_TYPE_E;

#define BUFFER_LENGTH 5000

_SOCKET_FUN int Fun_Socket_send_noblock(int nSocket, char *pBuf, int nBufLen, struct timeval *pTimeOut);

/*****************************************************
**	函数名  	:	Fun_Socket_OpenSession
**	功能描述	:	创建本地socket
**	输入函数	:	
type			:	socket类型
name		:	服务器路径名字
cli_path		:	客户端路径
**	返回参数	:	
	0	:	成功
	1	:	失败
**	作者	:	hjl
**	日期	:	2018.3.12
*****************************************************/
_SOCKET_FUN int Fun_Socket_OpenSession(SESSION_TYPE_E type,char *name,char *cli_path);
/*****************************************************
**	函数名  		:	Fun_Socket_send
**	功能描述	:	发送socket
**	输入函数	:	
nSocket				:	socket
pBuf					:	发送数据内容
nBufLen				:	发送数据长度
pTimeOut			:	超时时间,默认2秒

**	返回参数	:	
成功				:	发送长度
失败				:	-1
**	作者	:	hjl
**	日期	:	2018.3.12
*****************************************************/

_SOCKET_FUN int Fun_Socket_send(int nSocket, char *pBuf, int nBufLen, struct timeval *pTimeOut);
/*****************************************************
**	函数名  	:	Fun_Socket_recv
**	功能描述	:	接收socket
**	输入函数	:	
nSocket			:	socket
pBuf				:	接收数据内存
nBufLen			:	接收数据内存长度
pTimeOut		:	超时时间,默认2秒

**	返回参数	:	
成功	:	接收长度
失败	:	-1
**	作者	:	hjl
**	日期	:	2018.3.12
*****************************************************/

_SOCKET_FUN int Fun_Socket_recv(int nSocket, char *pBuf, int nBufLen, struct timeval *pTimeOut);


/*****************************************************
**	函数名  	:	Fun_Socket_CloseSessionToServer
**	功能描述	:	关闭套接字
**	输入函数	:	
nSocket			:	socket
pBuf				:	接收数据内存
nBufLen			:	接收数据内存长度
pTimeOut		:	超时时间,默认2秒

**	返回参数	:	

**	作者	:	hjl
**	日期	:	2018.3.12
*****************************************************/
_SOCKET_FUN void Fun_Socket_CloseSessionToServer(int nSocket);

/*****************************************************
**	函数名  	:	Fun_Socket_WaitForClient
**	功能描述	:	接收链接
**	输入函数	:	
nSocket			:	socket

**	返回参数	:	
成功	:	套接字
失败	:	-1
**	作者	:	hjl
**	日期	:	2018.3.12
*****************************************************/
_SOCKET_FUN int Fun_Socket_WaitForClient(int nSocket);

_SOCKET_FUN int Fun_Socket_send_block(int nSocket, char *pBuf, int nBufLen);


#endif

local_client.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/prctl.h>
#include <errno.h>
#include <signal.h>

#include <sys/socket.h>
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>
#include <sys/un.h>
#include <fcntl.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include"socket_commom.h"

#define UNIX_SOCKET_PATH	"/tmp/"
#define SEND_CFG_UNIX_FILE	"/tmp/webs_app_cfg_unix_file"
#define SEND_FD_UNIX_FILE	"/tmp/send_fd_unix_file"

static SINT32  accfd = 0;

static pthread_mutex_t client_mutex;
char* serverpath = "/tmp/server";
char* clientpath = "/tmp/client";

static pthread_mutex_t client_mutex;

int OpenClientSession(char *name,char *cli_path)
{
	int ret = -1;
	ret = Fun_Socket_OpenSession(SESSION_CLIENT, name, cli_path);
	pthread_mutex_init(&client_mutex, NULL);
	return ret;
}

int CloseClientSession(int nSocket)
{
	Fun_Socket_CloseSessionToServer(nSocket);
	pthread_mutex_destroy(&client_mutex);
	return 0;
}

int WebsApp_Recv_Cfg(int nSocket, unsigned char *pType, void *pRecvParam, struct timeval *pTimeOut)
{
	char csBuf[BUFFER_LENGTH];
	int nLen = 0;
	pthread_mutex_lock(&client_mutex);
	nLen = Fun_Socket_recv(nSocket, csBuf, BUFFER_LENGTH, pTimeOut);
	if(nLen <= 0)
	{
		pthread_mutex_unlock(&client_mutex);
		return nLen;
	}
	*pType = csBuf[0];
	if((nLen - 1) <= BUFFER_LENGTH)
	{
		memcpy(pRecvParam, csBuf + 1, nLen - 1);
	}else
	{
		printf("the nRecvLen is %d, too small", BUFFER_LENGTH);
		pthread_mutex_unlock(&client_mutex);
		return -1;
	}
	pthread_mutex_unlock(&client_mutex);
	return nLen;
}

int WebsApp_Send_Cfg(int nSocket, void *pSendParam, int nSendLen, struct timeval *pTimeOut)
{
	int ret = 0;
	pthread_mutex_lock(&client_mutex);
	ret = Fun_Socket_send(nSocket, pSendParam, nSendLen, pTimeOut);   
	pthread_mutex_unlock(&client_mutex);
	return ret;
}

typedef struct
{
	UINT32  ipAddress;
	UINT32  atnetMask;
	UINT32  gatewayIP; 
	UINT32  DnsServer1;	
	UINT32  DnsServer2;
}NetWork_Config_st;

typedef enum
{
	GET_NET_INFO,
	SET_NET_INFO,
}TYPE_E;

int Fun_GetNetWork_Config(NetWork_Config_st *NetWork_Config)
{
	NetWork_Config->ipAddress=inet_addr("10.82.16.62");
	NetWork_Config->atnetMask=inet_addr("255.255.255.0");
	NetWork_Config->gatewayIP=inet_addr("10.82.16.1");
	NetWork_Config->DnsServer1=inet_addr("10.82.1.3");
	NetWork_Config->DnsServer2=inet_addr("10.82.1.4");
	return 0;
}

int Prin_NET_Cfg(NetWork_Config_st NetStru)
{	
	char ipAddress[20];
	char atnetMask[20];
	char gatewayIP[20];
	char DnsServer1[20];
	char DnsServer2[20];
	
	inet_ntop(AF_INET,(void *)&( NetStru.ipAddress), (char *)ipAddress, sizeof(ipAddress));
	inet_ntop(AF_INET,(void *)&( NetStru.atnetMask), (char *)atnetMask, sizeof(atnetMask));
	inet_ntop(AF_INET,(void *)&( NetStru.gatewayIP), (char *)gatewayIP, sizeof(gatewayIP));
	inet_ntop(AF_INET,(void *)&( NetStru.DnsServer1), (char *)DnsServer1, sizeof(DnsServer1));
	inet_ntop(AF_INET,(void *)&( NetStru.DnsServer2), (char *)DnsServer2, sizeof(DnsServer2));
	
	printf("NetStru.ipAddress = %s\n",ipAddress);
	printf("NetStru.atnetMask = %s\n",atnetMask);
	printf("NetStru.gatewayIP = %s\n",gatewayIP);
	printf("NetStru.DnsServer1 = %s\n",DnsServer1);
	printf("NetStru.DnsServer2 = %s\n",DnsServer2);
	
	return 0;
}

void *HandleClientRequest(void)
{
    SINT32 fd = accfd;
    SINT8 *cBuf;
    UINT8 cType = 0;
    cBuf = (SINT8 *)malloc(4096);
	if(cBuf == NULL)
	{
		return NULL;
	}
	prctl(PR_SET_NAME,"HandlewebRequest",0,0,0);
	pthread_detach(pthread_self());
	
	while(1)
	{
		int ret;
        ret = WebsApp_Recv_Cfg(fd, &cType, cBuf, NULL);
		if(ret < 0)
		{
			goto EXIT;
		}
		else if(0 == ret)
		{
			continue;
		}
		
		printf("_________ctype=%x \n",cType);
		
		switch(cType)
        {
			case GET_NET_INFO:
			{
				printf("----- GET_NET_INFO -----\n");
				NetWork_Config_st NetWork_Config;
				memset(&NetWork_Config,0,sizeof(NetWork_Config));
				Fun_GetNetWork_Config(&NetWork_Config);
				if(-1 == WebsApp_Send_Cfg(fd,&NetWork_Config,sizeof(NetWork_Config),NULL))
				{	
                    printf("send data to webs failed!\n");
                    goto EXIT;
				}
			}
			break;
			case SET_NET_INFO:
			{
				printf("----- SET_NET_INFO -----\n");
				NetWork_Config_st NetWork_Config;
				memset(&NetWork_Config,0,sizeof(NetWork_Config));
				memcpy(&NetWork_Config , cBuf , sizeof(NetWork_Config));
				Prin_NET_Cfg(NetWork_Config);
				int ret =1;
				if(-1 == WebsApp_Send_Cfg(fd,&ret,sizeof(ret),NULL))
				{	
                    printf("send data to webs failed!\n");
                    goto EXIT;
				}
			}
			break;
            default:
				break;
		}
	}
	
EXIT:;
	if(fd > 0)
	{
		printf("webs handle thread will exits !\n");
		close(fd);
		fd = 0;
	}
	accfd = -1;
    return NULL;
}

void *Thread_WebServer()
{
    pthread_t ID;
	prctl(PR_SET_NAME,"Thread_Websapp",0,0,0);
	pthread_detach(pthread_self());
    while(1)
    {
        accfd = OpenClientSession(SEND_CFG_UNIX_FILE, UNIX_SOCKET_PATH);
        if(accfd > 0)
		{
			pthread_create(&ID, NULL, (void *)HandleClientRequest, NULL);
		}

        while(-1 != accfd)
        {
            sleep(1);
        }
        usleep(500000);
    }

    printf("Thread_Websapp exit!\n");
    pthread_exit(NULL);
}

SINT32 Fun_Websapp_Init(void)
{
    pthread_t ID;

    if(-1 == pthread_create(&ID, NULL, Thread_WebServer, NULL))
    {
        printf("Create thread of WebServer !\n");
        return -1;
    }

    return 0;
}

int main()
{
	Fun_Websapp_Init();
	while(1)
	{
		sleep(1);
	}
	return 0;
}

local_server.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/prctl.h>
#include <errno.h>
#include <signal.h>

#include <sys/socket.h>
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>
#include <sys/un.h>
#include <fcntl.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include"socket_commom.h"

#define UNIX_SOCKET_PATH	"/tmp/"
#define SEND_CFG_UNIX_FILE	"/tmp/webs_app_cfg_unix_file"
#define SEND_FD_UNIX_FILE	"/tmp/send_fd_unix_file"

static SINT32 websocfd = 0;
static SINT32 SessionID = 0;

static pthread_mutex_t server_mutex;

int OpenServerSession(char *name,char *cli_path)
{
	int ret = -1;
	ret = Fun_Socket_OpenSession(SESSION_SERVER, name, cli_path);
   
	pthread_mutex_init(&server_mutex, NULL);
	return ret;
}

int CloseServerSession(int nSocket)
{
	Fun_Socket_CloseSessionToServer(nSocket);
	pthread_mutex_destroy(&server_mutex);
	return 0;
}

int AcceptSession(int nSocket)
{
	return Fun_Socket_WaitForClient(nSocket);
}
int PassCfg(int nSocket, unsigned char cType, void *pSendParam, int nLen, struct timeval *pTimeOut)
{
	char csBuf[BUFFER_LENGTH];
	memcpy(csBuf, &cType, 1);
	memcpy(csBuf + 1, pSendParam, nLen);
	int ret = 0;
	
	pthread_mutex_lock(&server_mutex);
	ret = Fun_Socket_send(nSocket, csBuf, nLen + 1, pTimeOut);
    pthread_mutex_unlock(&server_mutex);
    return ret;
}

int GetCfg(int nSocket, unsigned char cType, void *pSendBuf, int nSendLen, void *pRecvBuf, int nRecvBufLen, struct timeval *pTimeOut)
{
	int ret = 0;
	char csBuf[BUFFER_LENGTH];
	int nLen = 0;
	memcpy(csBuf, &cType, 1);
	nLen += 1;
	if(nSendLen > 0)
	{
		memcpy(csBuf + 1, pSendBuf, nSendLen);
		nLen += nSendLen;
	}
    printf("get cType=%x\n", cType);

	pthread_mutex_lock(&server_mutex);
	if((ret = Fun_Socket_send(nSocket, csBuf, nLen, pTimeOut)) <= 0)
    {
		pthread_mutex_unlock(&server_mutex);
        return -1;
    }
    ret = Fun_Socket_recv(nSocket, pRecvBuf, nRecvBufLen, pTimeOut);
	if(ret == 0)
	{
		//printf("CmdType(%x) setting  Stuck , error reboot !", cType);
		//system("reboot");
	}
    pthread_mutex_unlock(&server_mutex);
    return ret;
}

static void initsocket(void)
{
	int socfd = 0;

	websocfd =  OpenServerSession(SEND_CFG_UNIX_FILE, UNIX_SOCKET_PATH);

	socfd = Fun_Socket_WaitForClient(websocfd);
	if(socfd>0)
	{
		if(SessionID>0)
		close(SessionID);
		SessionID =  socfd;
		printf("lyz test:socket OK Fun_Socket_WaitForClient SESSION =%d !!!\n",socfd);
	}
}

typedef struct
{
	UINT32  ipAddress;
	UINT32  atnetMask;
	UINT32  gatewayIP; 
	UINT32  DnsServer1;	
	UINT32  DnsServer2;
}NetWork_Config_st;

typedef enum
{
	GET_NET_INFO,
	SET_NET_INFO,
}TYPE_E;

int Fun_Get_NetPara_Cfg(NetWork_Config_st* NetStru)
{    
    memset(NetStru, 0, sizeof(NetWork_Config_st));
    if(GetCfg(SessionID, GET_NET_INFO, NULL, 0, NetStru, sizeof(NetWork_Config_st), NULL)== -1)
    {
		printf("Get network configuration failed\n");
        return -1;
    }
    return 0;
}

int Fun_Set_NET_Cfg(NetWork_Config_st NetStru)
{
    int ret = -1;
    if(GetCfg(SessionID, SET_NET_INFO,&NetStru, sizeof(NetStru), &ret, sizeof(ret), NULL) == -1)
	{
		printf("Set network configuration failed!\n");
		return -1;
	}
	return ret;
}

int Prin_NET_Cfg(NetWork_Config_st NetStru)
{	
	char ipAddress[20];
	char atnetMask[20];
	char gatewayIP[20];
	char DnsServer1[20];
	char DnsServer2[20];
	
	inet_ntop(AF_INET,(void *)&( NetStru.ipAddress), (char *)ipAddress, sizeof(ipAddress));
	inet_ntop(AF_INET,(void *)&( NetStru.atnetMask), (char *)atnetMask, sizeof(atnetMask));
	inet_ntop(AF_INET,(void *)&( NetStru.gatewayIP), (char *)gatewayIP, sizeof(gatewayIP));
	inet_ntop(AF_INET,(void *)&( NetStru.DnsServer1), (char *)DnsServer1, sizeof(DnsServer1));
	inet_ntop(AF_INET,(void *)&( NetStru.DnsServer2), (char *)DnsServer2, sizeof(DnsServer2));
	
	printf("NetStru.ipAddress = %s\n",ipAddress);
	printf("NetStru.atnetMask = %s\n",atnetMask);
	printf("NetStru.gatewayIP = %s\n",gatewayIP);
	printf("NetStru.DnsServer1 = %s\n",DnsServer1);
	printf("NetStru.DnsServer2 = %s\n",DnsServer2);
	
	return 0;
}

void *thread_webswait()
{
	pthread_detach(pthread_self());
	prctl(PR_SET_NAME, "thread_webswait");

	int socfd = 0;
	websocfd =  OpenServerSession(SEND_CFG_UNIX_FILE, UNIX_SOCKET_PATH);
	
	while(1)
	{
		socfd = Fun_Socket_WaitForClient(websocfd);
		if(socfd>0)
		{
			if(SessionID>0)
			close(SessionID);
			SessionID =  socfd;
			printf("lyz test:socket OK Fun_Socket_WaitForClient SESSION =%d !!!\n",socfd);
		}
	}
}

int main()
{
	pthread_t tid;

	//initsocket();
	int qos =10;
	int mode;

	pthread_create(&tid, NULL, thread_webswait, NULL);
	
	NetWork_Config_st NetStru={
		.ipAddress=inet_addr("10.82.16.61"),
		.atnetMask=inet_addr("255.255.255.0"),
		.gatewayIP=inet_addr("10.82.16.1"),
		.DnsServer1=inet_addr("10.82.1.3"),
		.DnsServer2=inet_addr("10.82.1.4"),
	};
	
	while(1)
	{
		printf("please enter the following type:\n");
		printf("1、information for GET_NET_INFO \n");
		printf("2、information for SET_NET_INFO \n");
		printf("please enter the mode:");
		while(1 != scanf("%d",&mode))
		{
			while(getchar() != '\n');
			printf("\n please enter the mode:");
		}
		switch(mode)
		{
			case 1:
				memset(&NetStru, 0 , sizeof(NetStru));
				Fun_Get_NetPara_Cfg(&NetStru);
				Prin_NET_Cfg(NetStru);
				break;
			case 2:
				if(-1 == Fun_Set_NET_Cfg(NetStru))
				{
					printf("Fun_Set_NET_Cfg fail !\n");
				}
				break;
			default:
				break;	
		}
	}
	return 0;
}

©️2020 CSDN 皮肤主题: 1024 设计师:上身试试 返回首页
实付 9.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值