windows linux—unix 跨平台通信集成控制系统
首先,我们可以用到这个开源的开发包:
mdk(Micro-Development-Kit)微量级软件开发包,提供几个常用类,主要实现了一个高性能的并发服务器引擎
使用c++开发,是一个跨平台的开发包,支持linux32/linux64/win32/win64的类库 。
mdk服务器引擎,提出面向业务的服务器开发模式,根据服务器业务层最关心的3件事,抽象出连接发生(OnConnect),消息到达(OnClose),连接关闭(OnClose)3个接口,让服务器端开发者可以全身心的投入业务逻辑的开发中。
特点: 提供分布式支持,自身是一个server-client的结合体(即做服务器使用的同时,也可以像client一样去连接别的服务器,组成分布式系统),并且io接口统一到onconnect onmsg onclose中,不必区别对待 事件轮巡使用的是原生epoll iocp实现,确保了对io响应速度的完全掌控 几乎等同于lock free的并发算法,保证并发效率
欢迎大家共同学习使用。
http://download.csdn.net/detail/wangyaninglm/8260299
或者是这里:
https://github.com/huoyu820125/Micro-Development-Kit
我们写客户端的时候可以用到里面 的socket类
socket.h如下:
// Socket.h: interface for the Socket class.
//
//////////////////////////////////////////////////////////////////////
/*********************************************************************** ************************************************************************/ #ifndef MDK_SOCKET_H
#define MDK_SOCKET_H #include <iostream> using namespace std; #ifdef WIN32
#include <windows.h> #define socklen_t int
#else
#include <errno.h> #include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <sys/types.h> #define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define closesocket close
typedef int SOCKET;
#endif #include <time.h>
#include <assert.h>
#include <string> namespace mdk
{ class Socket
{
public:
enum SocketError
{
seTimeOut = -2,
seSocketClose = -1,
seError = -3,
};
enum protocol
{
tcp = SOCK_STREAM,
udp = SOCK_DGRAM,
}; Socket();
Socket( SOCKET hSocket, protocol nProtocolType );
virtual ~Socket(); public:
//
SOCKET GetSocket();
/* */
bool Init(protocol nProtocolType);
/** */
void Close();
//
bool IsClosed(); //////////////////////////////////////////////////////////////////////////
/*
TCP */
int Send( const void* lpBuf, int nBufLen, int nFlags = 0 );
/* */
int Receive( void* lpBuf, int nBufLen, bool bCheckDataLength = false, long lSecond = 0, long lMinSecond = 0 ); //////////////////////////////////////////////////////////////////////////
/*UDP */
int SendTo( const char *strIP, int nPort, const void* lpBuf, int nBufLen, int nFlags = 0 );
/* */
int ReceiveFrom( char* lpBuf, int nBufLen, std::string &strFromIP, int &nFromPort, bool bCheckDataLength = false, long lSecond = 0, long lMinSecond = 0 ); /* */
bool Connect( const char* lpszHostAddress, unsigned short nHostPort ); /* */
bool StartServer( int nPort );
/*
*/
bool Accept(Socket& rConnectedSocket);
//
void GetWanAddress( std::string& strWanIP, int& nWanPort );
//
void GetLocalAddress( std::string& strWanIP, int& nWanPort );
/* */
bool SetSockMode( bool bWait = false );
/* */
bool SetSockOpt( int nOptionName, const void* lpOptionValue, int nOptionLen, int nLevel = SOL_SOCKET ); /*
*/
static bool SocketInit(void *lpVoid = NULL);
static void SocketDestory();
//
void GetLastErrorMsg( std::string &strError ); //
//
static bool InitForIOCP( SOCKET hSocket ); /* */
void Attach( SOCKET hSocket );
/* */
SOCKET Detach(); //
//
bool InitWanAddress();
//
//
bool InitLocalAddress(); protected:
/* */
bool TimeOut( long lSecond, long lMinSecond );
//
bool WaitData();
/* */
void GetAddress( const sockaddr_in &sockAddr, std::string &strIP, int &nPort );
/* */
bool Bind( unsigned short nPort, char *strIP = NULL );
/* */
bool Listen( int nConnectionBacklog = SOMAXCONN ); public:
private:
SOCKET m_hSocket;//
bool m_bBlock;//
bool m_bOpened;//
sockaddr_in m_sockAddr;
std::string m_strWanIP;
int m_nWanPort;
std::string m_strLocalIP;
int m_nLocalPort;
}; }//namespace mdk #endif // MDK_SOCKET_H
socket.cpp的实现:
// Socket.cpp: implementation of the Socket class.
//
//////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <iostream>
#include "Socket.h" #ifdef WIN32
//#include <windows.h>
#pragma comment ( lib, "ws2_32.lib" )
#endif using namespace std;
namespace mdk
{ Socket::Socket()
{
m_hSocket = INVALID_SOCKET;
m_bBlock = true;
m_bOpened = false;//
} Socket::Socket( SOCKET hSocket, protocol nProtocolType )
{
m_hSocket = hSocket;
m_bBlock = true;
m_bOpened = false;//
Init(nProtocolType);
InitWanAddress();
InitLocalAddress();
} Socket::~Socket()
{ } /* */
bool Socket::SocketInit(void *lpVoid)
{
#ifdef WIN32
// initialize Winsock library
WSADATA *lpwsaData = (WSADATA *)lpVoid;
WSADATA wsaData;
if (lpwsaData == NULL)
lpwsaData = &wsaData; WORD wVersionRequested = MAKEWORD(1, 1);
__int32 nResult = WSAStartup(wVersionRequested, lpwsaData);
if (nResult != 0)
return false; if (LOBYTE(lpwsaData->wVersion) != 1 || HIBYTE(lpwsaData->wVersion) != 1)
{
WSACleanup();
return false;
}
#endif
return true;
} void Socket::SocketDestory()
{
#ifdef WIN32
WSACleanup();
#endif
} void Socket::GetLastErrorMsg( string &strError )
{
char strErr[1024];
#ifdef WIN32
LPSTR lpBuffer;
DWORD dwErrorCode = WSAGetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dwErrorCode,
LANG_NEUTRAL,
(LPTSTR)&lpBuffer,
0,
NULL );
sprintf( strErr, "Socket Error(%ld):%s", dwErrorCode, lpBuffer );
strError = strErr;
LocalFree(lpBuffer); #else
sprintf( strErr, "socket errno(%d):%s\n", errno, strerror(errno) );
strError = strErr;
#endif
} bool Socket::InitForIOCP( SOCKET hSocket )
{
#ifdef WIN32
return 0 == setsockopt( hSocket,
SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
(char *)&(hSocket), sizeof(hSocket) );
#else
return true;
#endif
} //
SOCKET Socket::GetSocket()
{
return m_hSocket;
} void Socket::GetWanAddress( string& strWanIP, int& nWanPort )
{
nWanPort = m_nWanPort;
strWanIP = m_strWanIP;
return;
} bool Socket::InitWanAddress()
{
assert( INVALID_SOCKET != m_hSocket ); sockaddr_in sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
socklen_t nSockAddrLen = sizeof(sockAddr);
if ( SOCKET_ERROR == getpeername( m_hSocket,
(sockaddr*)&sockAddr, &nSockAddrLen ) ) return false;
m_nWanPort = ntohs(sockAddr.sin_port);
m_strWanIP = inet_ntoa(sockAddr.sin_addr); return true;
} void Socket::GetLocalAddress( string& strWanIP, int& nWanPort )
{
nWanPort = m_nLocalPort;
strWanIP = m_strLocalIP;
return;
} bool Socket::InitLocalAddress()
{
sockaddr_in sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
socklen_t nSockAddrLen = sizeof(sockAddr);
if ( SOCKET_ERROR == getsockname( m_hSocket,
(sockaddr*)&sockAddr, &nSockAddrLen )) return false;
m_nLocalPort = ntohs(sockAddr.sin_port);
m_strLocalIP = inet_ntoa(sockAddr.sin_addr); return true;
} /* */
bool Socket::Init(protocol nProtocolType)
{
if ( m_bOpened ) return true;
if ( m_hSocket == INVALID_SOCKET )
{
m_hSocket = socket( PF_INET, nProtocolType, 0 );
if ( m_hSocket == INVALID_SOCKET ) return false;
}
m_bOpened = true; return m_bOpened;
} /* */
bool Socket::Connect( const char *lpszHostAddress, unsigned short nHostPort)
{
assert( NULL != lpszHostAddress ); sockaddr_in sockAddr;
memset(&sockAddr,0,sizeof(sockAddr));
sockAddr.sin_family = AF_INET;
sockAddr.sin_addr.s_addr = inet_addr(lpszHostAddress);
sockAddr.sin_port = htons( nHostPort ); if ( SOCKET_ERROR != connect(m_hSocket, (sockaddr*)&sockAddr, sizeof(sockAddr)) )
{
InitWanAddress();
InitLocalAddress();
return true;
} return false;
} //
bool Socket::StartServer( int nPort )
{
if ( !this->Bind( nPort ) ) return false;
return this->Listen();
} //
bool Socket::IsClosed()
{
return !m_bOpened;
}
/* */
void Socket::Close()
{
if ( INVALID_SOCKET == m_hSocket ) return;
if ( m_bOpened )
{
closesocket(m_hSocket);
m_bOpened = false;
}
m_hSocket = INVALID_SOCKET;
return;
} /* */
void Socket::Attach(SOCKET hSocket)
{
m_hSocket = hSocket;
m_bBlock = true;
m_bOpened = true;//
InitWanAddress();
InitLocalAddress();
} /* */
SOCKET Socket::Detach()
{
SOCKET hSocket = m_hSocket;
m_hSocket = INVALID_SOCKET;
m_bBlock = true;
m_bOpened = false;//
return hSocket;
} /* */
int Socket::Receive( void* lpBuf, int nBufLen, bool bCheckDataLength, long lSecond, long lMinSecond )
{
if ( TimeOut( lSecond, lMinSecond ) ) return seTimeOut;//³¬Ê±
int nResult;
int nFlag = 0;
if ( bCheckDataLength ) nFlag = MSG_PEEK;
nResult = recv(m_hSocket, (char*)lpBuf, nBufLen, nFlag);
if ( 0 == nResult ) return seSocketClose;//
if ( SOCKET_ERROR != nResult ) return nResult;//ú //socket
#ifdef WIN32
int nError = GetLastError();
if ( WSAEWOULDBLOCK == nError ) return 0;//
return seError;
#else
if ( EAGAIN == errno ) return 0;//
return seError;
#endif
} /* */
int Socket::Send( const void* lpBuf, int nBufLen, int nFlags )
{
int nSendSize = send(m_hSocket, (char*)lpBuf, nBufLen, nFlags);
if ( 0 > nSendSize )
{
#ifdef WIN32
int nError = GetLastError();
return -1;
#else
return -1;
#endif
}
if ( nSendSize <= nBufLen ) return nSendSize;
return -1;
} /* */
bool Socket::Bind( unsigned short nPort, char *strIP )
{
memset(&m_sockAddr,0,sizeof(m_sockAddr));
m_sockAddr.sin_family = AF_INET;
if ( NULL == strIP ) m_sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
else
{
unsigned long lResult = inet_addr( strIP );
if ( lResult == INADDR_NONE ) return false;
m_sockAddr.sin_addr.s_addr = lResult;
}
m_sockAddr.sin_port = htons((unsigned short)nPort); return (SOCKET_ERROR != bind(m_hSocket, (sockaddr*)&m_sockAddr, sizeof(m_sockAddr)));
} /* */
bool Socket::Listen( int nConnectionBacklog )
{
return (SOCKET_ERROR != listen(m_hSocket, nConnectionBacklog));
} /* */
bool Socket::Accept(Socket& rConnectedSocket)
{
assert( INVALID_SOCKET == rConnectedSocket.m_hSocket );
socklen_t sockAddLen = 0;
rConnectedSocket.m_hSocket = accept(m_hSocket, NULL, &sockAddLen);
if ( INVALID_SOCKET == rConnectedSocket.m_hSocket )
{
#ifdef WIN32
if ( WSAEWOULDBLOCK == GetLastError() ) return true;//
#else
if ( EAGAIN == errno ) return true;//
#endif
return false;//socket
}
rConnectedSocket.m_bOpened = true;
rConnectedSocket.InitWanAddress();
rConnectedSocket.InitLocalAddress();
return true;
} /* */
bool Socket::SetSockOpt(
int nOptionName,
const void* lpOptionValue,
int nOptionLen,
int nLevel)
{
return ( SOCKET_ERROR != setsockopt(
m_hSocket,
nLevel,
nOptionName,
(char *)lpOptionValue,
nOptionLen));
} /* */
bool Socket::TimeOut( long lSecond, long lMinSecond )
{
if ( lSecond <= 0 && lMinSecond <= 0 ) return false;
//
timeval outtime;//
outtime.tv_sec = lSecond;
outtime.tv_usec =lMinSecond;
int nSelectRet;
#ifdef WIN32
FD_SET readfds = { 1, m_hSocket };
nSelectRet=::select( 0, &readfds, NULL, NULL, &outtime ); //
#else
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(m_hSocket, &readfds);
nSelectRet=::select(m_hSocket+1, &readfds, NULL, NULL, &outtime); //
#endif if ( SOCKET_ERROR == nSelectRet )
{
return true;
}
if ( 0 == nSelectRet ) //
{
return true;
} return false;
} //
bool Socket::WaitData()
{
int nSelectRet;
#ifdef WIN32
FD_SET readfds = { 1, m_hSocket };
nSelectRet=::select( 0, &readfds, NULL, NULL, NULL ); //
#else
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(m_hSocket, &readfds);
nSelectRet=::select(m_hSocket+1, &readfds, NULL, NULL, NULL); //
#endif
if ( SOCKET_ERROR == nSelectRet )
{
return false;
}
if ( 0 == nSelectRet ) //
{
return false;
}
return true;
} /* */
bool Socket::SetSockMode( bool bWait )
{
#ifdef WIN32
m_bBlock = bWait;
unsigned long ul = 1;
if ( m_bBlock ) ul = 0;
else ul = 1;
int ret = ioctlsocket( m_hSocket, FIONBIO, (unsigned long*)&ul );
if ( ret == SOCKET_ERROR )
{
return false;
}
#else
m_bBlock = bWait;
int flags = fcntl( m_hSocket, F_GETFL, 0 ); //
if ( !m_bBlock )
fcntl( m_hSocket, F_SETFL, flags|O_NONBLOCK );//
else
fcntl( m_hSocket, F_SETFL, flags&(~O_NONBLOCK&0xffffffff) );//
#endif
return true;
} /* */
int Socket::SendTo( const char *strIP, int nPort, const void* lpBuf, int nBufLen, int nFlags )
{
sockaddr_in sockAddr;
memset(&sockAddr,0,sizeof(sockAddr));
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons(nPort);
sockAddr.sin_addr.s_addr = inet_addr(strIP); int ret = sendto( m_hSocket, (const char*)lpBuf, nBufLen, nFlags,
(sockaddr*)&sockAddr, sizeof(sockaddr));
if (ret < 0) ret = -1;
return ret;
} /*
*/
int Socket::ReceiveFrom( char* lpBuf, int nBufLen, string &strFromIP, int &nFromPort, bool bCheckDataLength, long lSecond, long lMinSecond )
{
strFromIP = "";
nFromPort = -1;
if ( 0 >= nBufLen ) return 0;
sockaddr_in sockAddr;
socklen_t nAddrLen = sizeof(sockaddr);
/* waiting for receive data */
int nResult;
int nFlag = 0;
while ( true )
{
if ( TimeOut( lSecond, lMinSecond ) ) return seTimeOut;
if ( bCheckDataLength )nFlag = MSG_PEEK;
nResult = recvfrom(m_hSocket, lpBuf, nBufLen, nFlag, (sockaddr*)&sockAddr, &nAddrLen);
if ( nAddrLen > 0 ) GetAddress(sockAddr, strFromIP, nFromPort);
if ( SOCKET_ERROR == nResult ) //
{
#ifndef WIN32
if ( EAGAIN == errno ) return 0;//
return seError;
#else
int nError = GetLastError();
if ( 0 == nError )//
{
if ( MSG_PEEK == nFlag )//
{
recvfrom(m_hSocket, lpBuf, nBufLen, 0, (sockaddr*)&sockAddr, &nAddrLen);
}
continue;
}
if ( WSAEWOULDBLOCK == nError ) return 0;//
return seError;
#endif
}
break;
}
return nResult;
} void Socket::GetAddress( const sockaddr_in &sockAddr, string &strIP, int &nPort )
{
nPort = ntohs(sockAddr.sin_port);
strIP = inet_ntoa(sockAddr.sin_addr);
} }//namespace mdk
定义一个客户端的经常用的头文件:
//
// mac.h
// mac_client
//
// Created by mac mac on 13-5-8.
// Copyright (c) 2013年 __MyCompanyName__. All rights reserved.
// #ifndef mac_client_mac_h
#define mac_client_mac_h
////////////////////////////////////////////////////////////////////////////////////////
/*
1.注意中文标点,编译器不容易察觉
2.server 和client端的宏定义大小要统一
*/
/////////////////////////////////////////////////////////////////////////////////////////
#define MAX_SIZE 1024
#define MAX_NAME_LENGTH 64
#define MAX_PATH 260 //保持和windows端定义的一样
#define MAX_PATH_MAC 256 //苹果的最大长度
#define FALSE 0
#define TRUE 1 #define MAX_SEND_BUFFER 1024*4
#define MAX_RECV_BUFFER 1024*4 ///////////////////////////////////////////////////////////////////////////////////////// typedef struct Command //自定义命令结构体
{
int order;//命令序号
long datasize;
void * hwnd;//窗口句柄 }Command; typedef struct Server_Address //服务器地址
{ char strIP[3][MAX_PATH];//服务器ip
unsigned int uPort[3] ; //服务器端口
char remark[MAX_NAME_LENGTH];
}Server_Address; typedef struct _SYS_INFO //到时候得增加备注
{
Command cmd;
char remark[MAX_NAME_LENGTH]; //备注
char computer_name[MAX_NAME_LENGTH]; //
char user_name[MAX_NAME_LENGTH]; //
char sys_version[MAX_NAME_LENGTH]; //
char cpu_type[MAX_NAME_LENGTH]; //
char host_ip_address[MAX_NAME_LENGTH]; //内网ip
char ip_addresss[MAX_NAME_LENGTH]; //外网ip
char uuid[MAX_NAME_LENGTH]; //被控端的唯一标识 unsigned int cpu_num; //
unsigned int mem_total; //
int host_id; //
}SYS_INFO; enum
{
COMMAND_BIGIN = 20000, //命令开始
TOKEN_ONLINE, //上线命令
COMMAND_BREAK, //断开链接
COMMAND_UNINSTALL, //卸载
COMMAND_MODIFY_REMARK, //修改备注
///////////////////////////////////////////////////////////////////////////
COMMAND_MANAGER_FILE, //打开文件管理窗口
COMMAND_GET_DIRECTORY, //获取控制端主机根目录下所有文件信息
COMMAND_GET_REQUEST_DIRECTORY, //获取双击请求目录中所有文件信息
COMMAND_SEARCH_FILE, //文件搜索,还没做
COMMAND_WRONG_DIRECTORY, //目录为空或者不可读
COMMAND_DELETE_FILE, //删除文件
COMMAND_FILE_CLOSE, //关闭当前文件管理功能的链接
////////////////////////////////////////////////////////////////////////// COMMAND_MANAGER_CMD, //打开cmd管理窗口
TOKEN_CMD_NEXT, //等待下一个命令
COMMAND_SHELL, //控制端请求的shell命令
COMMAND_SHELL_CLOSE, //关闭shell
//////////////////////////////////////////////////////////////////////////
COMMAND_MANAGER_DOWNLOAD, //打开文件下载功能
TOKEN_DOWNLOAD_SETUP, //控制端发送文件下载连接和uuid
COMMAND_GET_FILEDATA, //请求文件数据
TOKEN_SENT_FILEDATA, //发送文件数据
TOKEN_CANT_GET_DATA, //给控制端发送消息文件不可读
////////////////////////////////////////////////////////////////////////
COMMAND_MANAGER_UPLOAD, //开启文件上传
TOKEN_UPLOAD_SETUP, //接受文件上传连接
COMMAND_SENT_UPLOAD_DATA, //发送上传文件数据
TOKEN_UPLOAD_DATA, //请求上传文件数据
TOKEN_UPLOAD_COMPLETE, //文件上传完成
COMMAND_RUN_PROGARM, //上传运行的文件 COMMAND_UPLOAD_CLOSE, //关闭上传进程和连接 }; #endif
客户端centos下面使用正常,开发环境codeblocks
客户端下载:
http://download.csdn.net/detail/wangyaninglm/8326249
服务器windows 7,xp都没有问题,开发环境visual studio 2010
服务端下载:
http://download.csdn.net/detail/wangyaninglm/8326321
整体界面:
命令行效果:
文件管理效果:
未完待续
。
。
。
windows linux—unix 跨平台通信集成控制系统的更多相关文章
- windows linux—unix 跨平台通信集成控制系统----文件搜索
跨平台的网络通信,跟设备的集成控制,牵扯到在各种平台下的文件搜索问题,windows下面的已经有了. 地址如下: http://blog.csdn.net/wangyaninglm/article/d ...
- windows linux—unix 跨平台通信集成控制系统----系统硬件信息获取
控制集成系统需要了解系统的各项硬件信息,之前我们设计的时候,习惯使用c函数来搞,后来可能发现程序的移植性收到了一些影响,比如unix内核的一些c函数在linux下面是没有的: 比如 苹果达尔文内核的如 ...
- Linux/Unix 多线程通信
线程间无需特别的手段进行通信,因为线程间可以共享数据结构,也就是一个全局变量可以被两个线程同时使用. 不过要注意的是线程间需要做好同步,一般用 mutex. 可以参考一些比较新的 UNIX/Linux ...
- Qt 条件编译 arm windows linux 判断 跨平台
如果代码里面有些判断需要不同的参数做判断: 办法:在pro文件里面做定义 方法1:直接定义一个宏:用的时候可以直接判断,这样做不好的地方是编译前需要重新切换一下宏 1)定义宏 DEFINES += _ ...
- windows和linux中搭建python集成开发环境IDE——如何设置多个python环境
本系列分为两篇: 1.[转]windows和linux中搭建python集成开发环境IDE 2.[转]linux和windows下安装python集成开发环境及其python包 3.windows和l ...
- 【转】windows和linux中搭建python集成开发环境IDE
本系列分为两篇: 1.[转]windows和linux中搭建python集成开发环境IDE 2.[转]linux和windows下安装python集成开发环境及其python包 3.windows和l ...
- shell脚本兼容linux/unix与windows/cygwin的基础(注意处理好CR, LF, CR/LF 回车 换行的问题)
shell脚本兼容linux/unix与windows/cygwin的基础 :统一文本格式为:unix文本格式,即于LF为换行符(推荐方案) 在notepad上设置:编辑->档案格式转换-> ...
- 使用Active Database Duplication创建跨平台Data Guard设置 (Windows/Linux) (Doc ID 881421.1)
Using Active Database Duplication to Create Cross Platform Data Guard Setup (Windows/Linux) (Doc ID ...
- (转)推荐一个在Linux/Unix上架设ASP.NET的 WEB服务器--Jexus
在Linux/Unix上架设ASP.NET WEB服务器,有两个可选方式,一种是Mono+XSP,一种是Mono+Jexus,其它的方式,比如 Apache+mod_mono.Nginx+FastCg ...
随机推荐
- React Native之ScrollView控件详解
概述 ScrollView在Android和ios原生开发中都比较常见,是一个 滚动视图控件.在RN开发中,系统也给我们提供了这么一个控件.不过在RN开发中 ,使用ScrollView必须有一个确定的 ...
- 用Python最原始的函数模拟eval函数的浮点数运算功能
前几天看一个网友提问,如何计算'1+1'这种字符串的值,不能用eval函数. 我仿佛记得以前新手时,对这个问题完全不知道如何下手. 我觉得处理括号实在是太复杂了,多层嵌套括号怎么解析呢?一些多余的括号 ...
- Java提升篇之反射的原理(二)
Java提升篇之通过反射越过泛型检查 /* *问题:在一个ArrayList<Integer>对象中,在这个集合中添加一个字符串. */ 在我们还没有学反射前,遇到这个问题都是无法实现的, ...
- JDBC的使用五大步骤以及查询操作-数据库编程(二)
jdbc的使用步骤 1.加载jdbc的驱动. 2.打开数据库的连接. 3.建立一个会话,然后执行增删改查等基本的操作. 4.对结果进行处理 5.对环境进行清理,比如关闭会话等. 查询操作 首先用Cla ...
- java模拟链表
java语言不存在指针,但是我们仍可以用相应的逻辑模拟链表的实现,下面这段代码就是我的一个小伙伴实现的: package com.brucezhang.test; public class ...
- iOS中的两种搜索方式UISearchDisplayController和UISearchController
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 以前iOS的搜索一般都使用UISearchDisplayCon ...
- 一个简单程序快速入门JDBC
首先创建jdbc的库,再在这个库里面创建一张users表. drop database if exists jdbc; create database if not exists jdbc; use ...
- 开发Nginx模块Helloworld
本文是对<深入理解Nginx>一书中的实例进行实战时的记录. 1模块目录结构 my_test_module/ ├── config └── ngx_http_mytest_module.c ...
- 数值分析:Hermite多项式
http://blog.csdn.net/pipisorry/article/details/49366047 Hermite埃尔米特多项式 在数学中,埃尔米特多项式是一种经典的正交多项式族,得名于法 ...
- JDK6和JDK7中String的substring()方法及其差异
翻译人员: 铁锚 翻译日期: 2013年11月2日 原文链接: The substring() Method in JDK 6 and JDK 7 在JDK6与JDK7这两个版本中,substri ...