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;
}