VC的链接顺序

CRT库在链接new, delete, DllMain这些符号的时候,使用的是弱外链接
MFC库同样也包含了new, delete, DllMain这几个符号,而MFC库必须在CRT库之前被链接才会成功。

如果link时出现了符号冲突,做下面的设置即可
project>properties>configuration properties>linker>input
在”Additional dependency”中依次增加 Nafxcwd.lib Libcmtd.lib
在add to “ignore specific library”中依次增加Nafxcwd.lib;Libcmtd.lib

VC服务程序调用远程资源

当VC服务程序调用远程资源时,经常返回路径不存在等问题
这是因为Windows中,服务程序以System用户登录,而不是桌面用户登录
这样就导致,虽然桌面程序已经映射网络资源,但System用户仍无法访问的问题
为了可以访问远程资源,可以调用API:WNetAddConnection2

BOOL AcessNetworkDrtive(CString szDevice,CString szDeviceName,CString szUsername,CString szPassword)
{
	DWORD dwRetVal;
	NETRESOURCE nr;

	memset(&nr, 0, sizeof (NETRESOURCE));
	nr.dwType = RESOURCETYPE_ANY;
	nr.lpLocalName = strDevice.GetBuffer(szDevice.GetLength());
	nr.lpRemoteName = szDeviceName.GetBuffer(szDeviceName.GetLength());
	nr.lpProvider = NULL;

	dwRetVal = WNetAddConnection2(&nr, szUsername, szUsername, CONNECT_UPDATE_PROFILE);

	if (dwRetVal != NO_ERROR)
	{
		CString cError;
		cError.Format(TEXT("[ERROR]WNetAddConnection2 Failed: %u\n"), dwRetVal);
		LogEvent(cError,TEXT("With remote name "),nr.lpRemoteName);
		return dwRetVal;
	}

	return 	dwRetVal;
}

创建进程API

Winexec
UINT WinExec(
LPCSTR lpCmdLine, 
UINT uCmdShow ); 

ShellExecute
HINSTANCE ShellExecute(
HWND hwnd, 
LPCTSTR lpOperation, 
LPCTSTR lpFile,
LPCTSTR lpParameters, 
LPCTSTR lpDirectory,
INT nShowCmd ); 

CreateProcess
BOOL CreateProcess(LPCTSTR lpApplicationName, 
LPTSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCTSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo, 
LPPROCESS_INFORMATION lpProcessInformation
); 

CPP类型转换

1、static_cast

这是应该首先选用的转换方式,一般用于在相关类型间进行转换或在继承链中进行转换。
其运作方式类似于隐式转换 (比如int转为float,或指针转换为 void*), 而且它可以调用显示转换(当然包括隐式转换)。

在很多情况下, 显示声明static_cast是不必要的,
但有一点需要指出的是应当尽量避免type(XXX) 与(type)XXX 语法(详情见下文)。
然而type(XXX,YYY) 是安全的,而且一定会去调用构造函数。

static_cast也可以在父类及子类之间进行。 当子类向父类转换时是可以顺利进行的。但父类向子类转换时,只要子类没有继承virtual父类,就可以一直进行。但是它从父类转为子类时,不会做任何检查,即使类型不完全匹配。

2、const_cast

用来向一个变量增加或删除const属性。 其他任何C++ casts都无法完成此任务。
需要指出的是,当变量为const,该操作符是未定义的。

用它来声明一个非const类型的const引用是安全的。
当重载const类型的类成员变量时,该转换十分有用。
它也可以用来把一个对象增加const属性,比如调用重载的方法。

const_cast也适用于volatile,但很少见。

3、dynamic_cast

一般用来解决多态问题。你可以把指针或参考转换为任何继承链上的类型。
(一个多态类型至少用一个虚函数,无论是声明还是继承的)。
当从子类转换为父类时,dynamic_cast一定会成功。但从父类转换为子类,dynamic_cast会确保对象为子类的一个完全实现。

dynamic_cast将返回其是否可能。如果无法转换,他将返回NULL(对指针),或抛出std::bad_cast异常(对参考)。

dynamic_cast有一些限制:
如果在继承链中,同一类型有多个对象(dreaded diamond)同时你没有使用虚接口,转换不会进行。
他也只能应用于public继承,当protect或private继承时,会失败。

注意:
dynamic_cast需要编译器支持RTTI(运行时类型识别)。

4、reinterpret_cast

这是最危险的转换方式,慎用。 它直接把一种类型转换为另一种
(比如把值从一种指针转换为另一种指针,或把指针储存在int中, 或其他让人讨厌的事情)

使用reinterpret_cast,唯一能保证的是,当你从结构转回为原类型时,你能得到相同的结果。
当然,reinterpret_cast也有一些转换无法进行。

他通常用于比较奇怪的转换,或bit操作,比图把raw数据流转换为实际数据,或把数据储存在对齐指针的低字节。
当其他转换无法使用时,可以尝试reinterpret_cast

5、C-style cast
C-style cast 是使用(type)object 或 type(object)的转换方式。
C-style cast 被定义为下列转换中第一个成功返回的:
const_cast
static_cast
static_cast, then const_cast
reinterpret_cast
reinterpret_cast, then const_cast

在一些时候,他可以被用来替代其他casts,但用于他最后可能会调用reinterpret_cast(应显示调用),因此C-style cast是十分危险的。
除非你能保证,不会调用reinterpret_cast,或者reinterpret_cast一定会失败,否则不要轻易使用。即使如此,也应该考虑显示调用上面的转换。

当使用static_cast时,C-style casts 也可以忽略权限控制,这意味着他可以进行其他cast无法进行的操作。
这是避免C-style casts的一个不错的理由。

(翻译自Stack Overflow的一个帖子,水平有限,哈哈)

参考资料:
http://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-and-reinterpret-cast-be-used
http://www.cplusplus.com/doc/tutorial/typecasting/
http://en.wikibooks.org/wiki/C%2B%2B_Programming/Programming_Languages/C%2B%2B/Code/Statements/Variables/Type_Casting

VC计算CString摘要

1、VC计算字符串MD5摘要

//输入:要计算摘要的字符串
//输出:128位MD5摘要
#include <wincrypt.h>
CString szResult;

CString CDigestDlg::CalcMD5(CString strContent)
{
  DWORD dwLength=0;
  BYTE* pbContent=NULL;

  dwLength = (DWORD)strContent.GetLength();
  pbContent = new BYTE[dwLength];
  memcpy(pbContent,strContent.GetBuffer(dwLength),dwLength);

  //计算MD5编码
  HCRYPTPROV hCryptProv; 
  HCRYPTHASH hHash; 
  BYTE byteMD5[16]; 
  DWORD dwHashLen=16;
  CString szResult;

  if(CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) 
  {
    if(CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash)) 
    {
      if(CryptHashData(hHash, pbContent, dwLength, 0))
      {

        if(CryptGetHashParam(hHash, HP_HASHVAL, byteMD5, &dwHashLen, 0)) 
        {
          szResult.Format(TEXT("%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"),
            byteMD5[0],byteMD5[1],byteMD5[2],byteMD5[3],byteMD5[4],byteMD5[5],byteMD5[6],byteMD5[7]
            ,byteMD5[8],byteMD5[9],byteMD5[10],byteMD5[11],byteMD5[12],byteMD5[13],byteMD5[14],byteMD5[15]);
        }
        else
        {
          szResult=TEXT("Error getting hash param");
        }

      }
      else
      {
        szResult=TEXT("Error hashing data");
      }
    }
    else
    {
      szResult=TEXT("Error creating hash");
    }
  }
  else
  {
    szResult=TEXT("Error acquiring context");
  }

  CryptDestroyHash(hHash); 
  CryptReleaseContext(hCryptProv, 0); 
  delete[] pbContent;
  pbContent=NULL;

  return szResult;
}

2、VC计算字符串SHA1摘要

//输入:要计算摘要的字符串
//输出:160位SHA1摘要
#include <wincrypt.h>
CString szResult;

CString CDigestDlg::CalcSHA1(CString strContent)
{
  DWORD dwLength=0;
  BYTE* pbContent=NULL;

  dwLength = (DWORD)strContent.GetLength();
  pbContent = new BYTE[dwLength];
  memcpy(pbContent,strContent.GetBuffer(dwLength),dwLength);

  //计算MD5编码
  HCRYPTPROV hCryptProv; 
  HCRYPTHASH hHash; 
  BYTE byteSHA1[20]; 
  DWORD dwHashLen=20;
  CString szResult;

  if(CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) 
  {
    if(CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hHash)) 
    {
      if(CryptHashData(hHash, pbContent, dwLength, 0))
      {

        if(CryptGetHashParam(hHash, HP_HASHVAL, byteSHA1, &dwHashLen, 0)) 
        {
          szResult.Format(TEXT("%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"),
            byteSHA1[0],byteSHA1[1],byteSHA1[2],byteSHA1[3],byteSHA1[4],byteSHA1[5],byteSHA1[6],byteSHA1[7],
            byteSHA1[8],byteSHA1[9],byteSHA1[10],byteSHA1[11],byteSHA1[12],byteSHA1[13],byteSHA1[14],byteSHA1[15],
            byteSHA1[16],byteSHA1[17],byteSHA1[18],byteSHA1[19]);
        }
        else
        {
          szResult=TEXT("Error getting hash param");
        }

      }
      else
      {
        szResult=TEXT("Error hashing data");
      }
    }
    else
    {
      szResult=TEXT("Error creating hash");
    }
  }
  else
  {
    szResult=TEXT("Error acquiring context");
  }

  CryptDestroyHash(hHash); 
  CryptReleaseContext(hCryptProv, 0); 
  delete[] pbContent;
  pbContent=NULL;

  return szResult;
}

VC计算文件摘要

1、VC计算文件MD5摘要

//输入:文件路径
//输出:128位MD5摘要
#include <wincrypt.h>
CString szResult;

CString CMD5AndSHA1Dlg::CalcMD5(CString strFilePath)
{
  //读取文件
  CFile inFile;
  CFileException ex;
  DWORD dwLength=0;
  BYTE* pbContent=NULL;
  BOOL bRet;

  bRet=inFile.Open(strFilePath,CFile::modeRead | CFile::typeBinary | CFile::shareDenyWrite,&ex);
  if(bRet==FALSE)
  {
    return TEXT("Error opening file");;
  }

  dwLength = (DWORD)inFile.GetLength();
  pbContent = new BYTE[dwLength];
  if(pbContent==NULL)
  {
    return TEXT("Error not enough memory");;
  }
  inFile.Read(pbContent,dwLength);
  inFile.Close();

  //计算MD5编码
  HCRYPTPROV hCryptProv; 
  HCRYPTHASH hHash; 
  BYTE byteMD5[16]; 
  DWORD dwHashLen=16;
  CString szResult;

  if(CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) 
  {
    if(CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash)) 
    {
      if(CryptHashData(hHash, pbContent, dwLength, 0))
      {

        if(CryptGetHashParam(hHash, HP_HASHVAL, byteMD5, &dwHashLen, 0)) 
        {
          szResult.Format(TEXT("%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"),
            byteMD5[0],byteMD5[1],byteMD5[2],byteMD5[3],byteMD5[4],byteMD5[5],byteMD5[6],byteMD5[7]
            ,byteMD5[8],byteMD5[9],byteMD5[10],byteMD5[11],byteMD5[12],byteMD5[13],byteMD5[14],byteMD5[15]);
        }
        else
        {
          szResult=TEXT("Error getting hash param");
        }

      }
      else
      {
        szResult=TEXT("Error hashing data");
      }
    }
    else
    {
      szResult=TEXT("Error creating hash");
    }
  }
  else
  {
    szResult=TEXT("Error acquiring context");
  }

  CryptDestroyHash(hHash); 
  CryptReleaseContext(hCryptProv, 0); 
  delete[] pbContent;
  pbContent=NULL;

  return szResult;
}

2、VC计算文件SHA1摘要

//输入:文件路径(文件必须小于2^64bit)
//输出:160位SHA1摘要
#include <wincrypt.h>
CString szResult;

CString CMD5AndSHA1Dlg::CalcSHA1(CString strFilePath)
{
  //读取文件
  CFile inFile;
  CFileException ex;
  DWORD dwLength=0;
  BYTE* pbContent=NULL;
  BOOL bRet;

  bRet=inFile.Open(strFilePath,CFile::modeRead | CFile::typeBinary | CFile::shareDenyWrite,&ex);
  if(bRet==FALSE)
  {
    return TEXT("Error opening file");;
  }

  dwLength = (DWORD)inFile.GetLength();
  pbContent = new BYTE[dwLength];
  if(pbContent==NULL)
  {
    return TEXT("Error not enough memory");;
  }
  inFile.Read(pbContent,dwLength);
  inFile.Close();

  //计算MD5编码
  HCRYPTPROV hCryptProv; 
  HCRYPTHASH hHash; 
  BYTE byteSHA1[20]; 
  DWORD dwHashLen=20;
  CString szResult;

  if(CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) 
  {
    if(CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hHash)) 
    {
      if(CryptHashData(hHash, pbContent, dwLength, 0))
      {

        if(CryptGetHashParam(hHash, HP_HASHVAL, byteSHA1, &dwHashLen, 0)) 
        {
          szResult.Format(TEXT("%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"),
            byteSHA1[0],byteSHA1[1],byteSHA1[2],byteSHA1[3],byteSHA1[4],byteSHA1[5],byteSHA1[6],byteSHA1[7],
            byteSHA1[8],byteSHA1[9],byteSHA1[10],byteSHA1[11],byteSHA1[12],byteSHA1[13],byteSHA1[14],byteSHA1[15],
            byteSHA1[16],byteSHA1[17],byteSHA1[18],byteSHA1[19]);
        }
        else
        {
          szResult=TEXT("Error getting hash param");
        }

      }
      else
      {
        szResult=TEXT("Error hashing data");
      }
    }
    else
    {
      szResult=TEXT("Error creating hash");
    }
  }
  else
  {
    szResult=TEXT("Error acquiring context");
  }

  CryptDestroyHash(hHash); 
  CryptReleaseContext(hCryptProv, 0); 
  delete[] pbContent;
  pbContent=NULL;

  return szResult;
}

函数调用约定

1.STDCALL
微软制定的c语言调用约定,也就是传说中的WINAPI
参数从右向左进行压栈(微软官方文档说从左向右压栈),返回值存在eax中,
被调用函数清理栈,不允许变长参数列表
函数名前增加_,函数名后增加@和参数个数(32位机器上一定被4整除)
ret指令中,有可选参数指定有多少字节需要弹栈

2.CDECL
c语言的默认调用约定
参数从右向左进行压栈,返回值存在eax中,
调用函数清理栈,可用变长参数列表
函数名前会增加_

3.FASTCALL
非跨编译器的c语言调用约定,
前2-3个4字节内的参数被存放到寄存器(edx,eax,ecx)中,其他参数,或大于4字节的参数,按从右到左的顺序被存放在栈中
多数情况下,调用函数负责清理栈
仅适用于参数少,而且实时性要求很高的情况下
函数名前增加@,函数名后增加@和参数个数

4.THISCALL
cpp的调用约定
参数从右向左进行压栈,返回值存在eax中,this指针存在ecx中
每种编译器对函数名称有不同的修饰方法,但基于重载的需要,一般都会增加参数类型和类名
当使用extern “C”的时候,cpp编译器会使用c语言的修饰方法来修饰函数名,这样就可以方便的供别人调用了。

MinGW中Socket基础

1.客户端简单例子
myc.c

#define MINGW32

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef MINGW32
#include <winsock2.h>
#else
#include <sys/socket.h>
#include <arpa/inet.h>
#endif

#define MAXLINE 1024

int main(int argc,char **argv) 
{
  int  sockfd,n;
  char  receline[MAXLINE+1];
  struct  sockaddr_in serveraddr;

  //输入参数太少,退出
  if(argc != 2) 
  { 
    printf("Usage :%s  IP_address\n", argv[0]);
    exit(0);
  }

  #ifdef MINGW32
  //Winsows下启用socket
  WSADATA wsadata;
  if(WSAStartup(MAKEWORD(1,1),&wsadata)==SOCKET_ERROR)
  {
    printf("WSAStartup() fail\n");
    exit(0);
  }
  #endif
  
  //建立socket
  if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
  {
    printf("socket() fail\n");
    exit(0);
  }

  //设置协议及Port
  memset(&serveraddr,0,sizeof(serveraddr));
  serveraddr.sin_family = AF_INET;
  serveraddr.sin_port=htons(1024);

  //设置IP
  serveraddr.sin_addr.s_addr=inet_addr(argv[1]);

  //连接
  if(connect(sockfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr))==-1)
  {
    printf("connect() fail\n");
    exit(0);
  }

  //读取数据并输入到标准输出
  #ifdef MINGW32
  while((n=recv(sockfd,receline,MAXLINE,0))>0)
  #else
  while((n=read(sockfd,receline,MAXLINE))>0)
  #endif
  { 
    receline[n]=0;
    if(fputs(receline,stdout)==EOF)
    {
      printf("fputs() error\r\n");
    }
  }

  //没有获取数据
  if(n<0) 
  {
    printf("read() fail\n");
  }

  #ifdef MINGW32
  //Winsows下关闭socket
  closesocket(sockfd);
  WSACleanup();
  #endif

  exit(0);
}
&#91;/code&#93;

2.服务端简单例子
mys.c
&#91;code lang="c"&#93;
#define MINGW32

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef MINGW32
#include <winsock2.h>
#else
#include <sys/socket.h>
#include <arpa/inet.h>
#endif

#define LISTENQ 10

int main(int argc,char *argv[])
{
  int  serverfd,connectfd;
  struct  sockaddr_in serveraddr;
  char  buff[1024];
  time_t  tlick;
  int  iRet;

  #ifdef MINGW32
  //Winsows下启用socket
  WSADATA wsadata;
  if(WSAStartup(MAKEWORD(1,1),&wsadata)==SOCKET_ERROR)
  {
    printf("WSAStartup() fail\n");
    exit(0);
  }
  #endif

  //新建socket
  printf("socket()\n");
  serverfd=socket(AF_INET,SOCK_STREAM,0);
  if(serverfd==-1)
  {
    printf("socket() fail\n");
    exit(0);
  }

  //清零
  memset(&serveraddr,0,sizeof(serveraddr));

  //设置协议
  serveraddr.sin_family=AF_INET;
  //设置IP
  serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);
  //设置Port
  serveraddr.sin_port=htons(1024);

  //绑定端口,监听1024端口的任何请求
  printf("bind()\n");
  iRet=bind(serverfd,(struct sockaddr*)&serveraddr,sizeof(serveraddr));
  if(iRet==-1)
  {
    printf("bind() fail\n");
    exit(0);
  }

  //监听端口,最大并发数10
  printf("listen()\n");
  iRet=listen(serverfd,LISTENQ);
  if(iRet==-1)
  {
    printf("listen() fail\n");
    exit(0);
  }

  //接受请求,发送主机时间
  for(;;)
  {
    printf("Waiting for connection...\n");
    //接受请求
    connectfd=accept(serverfd,(struct sockaddr*)NULL,NULL);
    //获取时间    
    tlick=time(NULL);
    //格式化时间    
    snprintf(buff,sizeof(buff),"From mys:\n%s",ctime(&tlick));
    //写入时间
    //关闭请求
    #ifdef MINGW32
    send(connectfd,buff,strlen(buff),0);
    closesocket(connectfd);
    #else
    write(connectfd,buff,strlen(buff));
    close(connectfd);
    #endif
  }

  #ifdef MINGW32
  //Winsows下关闭socket
  closesocket(serverfd);
  WSACleanup();
  #endif

  //退出
  exit(0);
}

3.Makefile

all:mys myc

mys:mys.c
	gcc -g -o mys mys.c -l wsock32

myc:myc.c
	gcc -g -o myc myc.c -l wsock32

clean:
	del *~ *.o *.exe

VC中Socket通信基础

1.客户端程序
SocketClientBlock.c

#pragma comment(lib, "WS2_32")

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>

#define BUF_SIZE (1024)

int main(int argc,char **argv) 
{
  WSADATA wsadata;

  int  sockfd,n;
  char  receline[BUF_SIZE];
  struct  sockaddr_in serveraddr;

  //Winsows下启用socket
  if(WSAStartup(MAKEWORD(1,1),&wsadata)==SOCKET_ERROR)
  {
    printf("WSAStartup() fail\n");
    exit(0);
  }

  //建立socket
  if((sockfd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
  {
    printf("socket() fail\n");
    exit(0);
  }

  //设置协议,IP及Port
  memset(&serveraddr,0,sizeof(serveraddr));
  serveraddr.sin_family = AF_INET;
  serveraddr.sin_port=htons(1024);
  serveraddr.sin_addr.s_addr=inet_addr("127.0.0.1");
  /*
  //hostname转ip
  hostent *hostEnt = gethostbyname( strRemote );
  if( hostEnt != NULL )
  {
    lIPAddress = ((in_addr*)hostEnt->h_addr)->s_addr;
    serveraddr.sin_addr.s_addr = lIPAddress;
  }
  else
  {
    serveraddr.sin_addr.s_addr = inet_addr( strRemote );
  }
  */

  //连接
  if(connect(sockfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr))==SOCKET_ERROR)
  {
    printf("connect() fail\n");
    exit(0);
  }

  //读取数据并输入到标准输出
  while((n=recv(sockfd,receline,BUF_SIZE,0))!=SOCKET_ERROR)
  { 
    receline[n]=0;
    if(fputs(receline,stdout)==EOF)
    {
      printf("fputs() error\r\n");
    }
  }

  //没有获取数据
  if(n<0) 
  {
    printf("read() fail\n");
  }

  //Winsows下关闭socket
  closesocket(sockfd);
  WSACleanup();

  exit(0);
}
&#91;/code&#93;

2.服务端程序,阻塞
SocketServerBlock.c
&#91;code lang="c"&#93;
#pragma comment(lib, "WS2_32")

#include <winsock.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define MAX_CONNECT_NUM (10)

int main(int argc,char** argv)
{
  WSADATA wsadata;
  struct  sockaddr_in serveraddr;
  int  socketflag,connectflag;

  time_t  time_tick;
  char  buff[1024];
  
  //Winsows下启用网络
  if(WSAStartup(MAKEWORD(1,1),&wsadata)==SOCKET_ERROR)
  {
    printf("WSAStartup() fail,%d\n", WSAGetLastError());
    exit(0);
  }
  
  //新建socket
  if(INVALID_SOCKET==(socketflag=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)))
  {
    printf("socket() fail\n");
    exit(0);
  }

  //清零,设置协议,设置IP,设置Port
  memset(&serveraddr,0,sizeof(serveraddr));
  serveraddr.sin_family=AF_INET;
  serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);
  serveraddr.sin_port=htons(1024);

  //绑定端口,监听1024端口的任何请求
  if(SOCKET_ERROR==bind(socketflag,(struct sockaddr*)&serveraddr,sizeof(serveraddr)))
  {
    printf("bind() fail\n");
    exit(0);
  }

  //监听端口,最大并发数MAX_CONNECT_NUM
  if(SOCKET_ERROR==listen(socketflag,MAX_CONNECT_NUM))
  {
    printf("listen() fail\n");
    exit(0);
  }

  //接受请求,发送主机时间
  for(;;)
  {
    struct  sockaddr clientaddr;
    int iLen = sizeof(clientaddr);
    printf("Waiting for connection...\n");

    //接受连接
    connectflag=accept(socketflag,&clientaddr,&iLen);
    if(INVALID_SOCKET==connectflag)
    {
      printf("accept() fail\n");
      exit(0);
    }

    //获取时间,并格式化
    time_tick=time(NULL);
    sprintf(buff,"From mys:\n%s",ctime(&time_tick));
    //写入时间
    if(SOCKET_ERROR==send(connectflag,buff,strlen(buff),0))
    {
      printf("send() fail\n");
      exit(0);
    }

    //关闭连接
    closesocket(connectflag);
  }

  //Winsows下关闭socket及网络
  if(SOCKET_ERROR==closesocket(socketflag))
  {
    printf("closesocket() fail\n");
    exit(0);
  }
  WSACleanup();

  //退出
  exit(0);
}

3.服务端程序,阻塞,有Select
SocketServerBlockSelect.c

#pragma comment(lib, "WS2_32")

#include <winsock.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define MAX_CONNECT_NUM (10)

int main(int argc,char** argv)
{
  WSADATA wsadata;
  struct  sockaddr_in serveraddr;
  int  socketflag,connectflag;

  fd_set  fdR;
  struct  timeval timeout ={1,500};

  time_t  time_tick;
  char  buff[1024];
  
  //Winsows下启用网络
  if(WSAStartup(MAKEWORD(1,1),&wsadata)==SOCKET_ERROR)
  {
    printf("WSAStartup() fail,%d\n", WSAGetLastError());
    exit(0);
  }
  
  //新建socket
  if(INVALID_SOCKET==(socketflag=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)))
  {
    printf("socket() fail\n");
    exit(0);
  }

  //清零,设置协议,设置IP,设置Port
  memset(&serveraddr,0,sizeof(serveraddr));
  serveraddr.sin_family=AF_INET;
  serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);
  serveraddr.sin_port=htons(1024);

  //绑定端口,监听1024端口的任何请求
  if(SOCKET_ERROR==bind(socketflag,(struct sockaddr*)&serveraddr,sizeof(serveraddr)))
  {
    printf("bind() fail\n");
    exit(0);
  }

  //监听端口,最大并发数MAX_CONNECT_NUM
  if(SOCKET_ERROR==listen(socketflag,MAX_CONNECT_NUM))
  {
    printf("listen() fail\n");
    exit(0);
  }

  //接受请求,发送主机时间
  for(;;)
  {
    printf("Waiting for connection...\n");

    FD_ZERO(&fdR);
    FD_SET(socketflag, &fdR);
        switch (select(0, &fdR, NULL, NULL,&timeout)) 
    {
    case SOCKET_ERROR:
      printf("Socket Error...\n");
      break;
    case 0:
      printf("Time Out Here...\n");
      break;
    default:
      printf("Connection is coming...\n");
      if (1)
      {
        struct  sockaddr clientaddr;
        int iLen = sizeof(clientaddr);

        //接受连接
        connectflag=accept(socketflag,&clientaddr,&iLen);
        if(INVALID_SOCKET==connectflag)
        {
          printf("accept() fail\n");
          exit(0);
        }

        //获取时间,并格式化
        time_tick=time(NULL);
        sprintf(buff,"From mys:\n%s",ctime(&time_tick));
        //写入时间
        if(SOCKET_ERROR==send(connectflag,buff,strlen(buff),0))
        {
          printf("send() fail\n");
          exit(0);
        }

        //关闭连接
        closesocket(connectflag);
      }
      break;
        }
  }

  //Winsows下关闭socket及网络
  if(SOCKET_ERROR==closesocket(socketflag))
  {
    printf("closesocket() fail\n");
    exit(0);
  }
  WSACleanup();

  //退出
  exit(0);
}

4.服务端程序,非阻塞
SocketServerNonBlock.c

#pragma comment(lib, "WS2_32")

#include <winsock.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define MAX_CONNECT_NUM (10)

int main(int argc,char** argv)
{
  WSADATA wsadata;
  struct  sockaddr_in serveraddr;
  int  socketflag,connectflag;

  time_t  time_tick;
  char  buff[1024];

  unsigned long flag=1;
  
  //Winsows下启用网络
  if(WSAStartup(MAKEWORD(1,1),&wsadata)==SOCKET_ERROR)
  {
    printf("WSAStartup() fail,%d\n", WSAGetLastError());
    exit(0);
  }
  
  //新建socket
  if(INVALID_SOCKET==(socketflag=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)))
  {
    printf("socket() fail\n");
    exit(0);
  }

  //非阻塞方式
  if(ioctlsocket(socketflag,FIONBIO,&flag)!=0)
  {
    printf("ioctlsocket() fail\n");
    exit(0);
  }

  //清零,设置协议,设置IP,设置Port
  memset(&serveraddr,0,sizeof(serveraddr));
  serveraddr.sin_family=AF_INET;
  serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);
  serveraddr.sin_port=htons(1024);

  //绑定端口,监听1024端口的任何请求
  if(SOCKET_ERROR==bind(socketflag,(struct sockaddr*)&serveraddr,sizeof(serveraddr)))
  {
    printf("bind() fail\n");
    exit(0);
  }

  //监听端口,最大并发数MAX_CONNECT_NUM
  if(SOCKET_ERROR==listen(socketflag,MAX_CONNECT_NUM))
  {
    printf("listen() fail\n");
    exit(0);
  }

  //接受请求,发送主机时间
  for(;;)
  {
    struct  sockaddr clientaddr;
    int iLen = sizeof(clientaddr);
    printf("Waiting for connection...\n");

    //接受连接
    connectflag=accept(socketflag,&clientaddr,&iLen);
    if(INVALID_SOCKET==connectflag)
    {
      printf("no connection\n");
      Sleep(1500);
    }
    else
    {
      printf("Connection is coming...\n");
      //获取时间,并格式化
      time_tick=time(NULL);
      sprintf(buff,"From mys:\n%s",ctime(&time_tick));
      //写入时间
      if(SOCKET_ERROR==send(connectflag,buff,strlen(buff),0))
      {
        printf("send() fail\n");
        exit(0);
      }

      //关闭连接
      closesocket(connectflag);
    }
  }

  //Winsows下关闭socket及网络
  if(SOCKET_ERROR==closesocket(socketflag))
  {
    printf("closesocket() fail\n");
    exit(0);
  }
  WSACleanup();

  //退出
  exit(0);
}

c与cpp输出16进制,8进制及ASCII

1.c

#include <stdio.h>
int main(int argc,char **argv)
{
	for(int i=0;i<=127;i++)
	{
		printf("%X-%03o-%c\n",i,i,i);
	}
	return 0;
}

2.cpp

#include <iostream>
#include <iomanip>

using namespace std;

int main(int argc,char **argv)
{
	for(int i=0;i<=127;i++)
	{
		cout<<setw(2)<<setfill('0')<<hex<<i<<"-"<<setw(3)<<setfill('0')<<oct<<i<<"-"<<dec<<(char)i<<endl;
	}

	return 0;
}