*C++ Windows UDP 函数设置
WORD wVersionRequested;
WSADATA wsaData;
int sockerr;
SOCKET sockComm;
SOCKADDR_IN addrCtrl;
SOCKADDR_IN addrHost;
int nZero=0;
int err=0;
int imode=1; //0-阻塞方式,1-非阻塞方式
int max_timeout=3000;超时时间3s Windows ms 为单位
SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS);
wVersionRequested = MAKEWORD(2, 2);
sockerr = WSAStartup(wVersionRequested, &wsaData);
if(sockerr != 0)
{
// AfxMessageBox(_T("Socket版本错误"));
return -1;
}
if(LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
{
WSACleanup();
// AfxMessageBox(_T("Socket版本错误"));
return -2;
}
sockComm = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);//0
addrCtrl.sin_family = AF_INET;
addrCtrl.sin_port = htons(2000);
addrCtrl.sin_addr.S_un.S_addr = 0;
addrCtrl.sin_addr.S_un.S_addr = 192;
addrCtrl.sin_addr.S_un.S_addr |= (168<<8);
addrCtrl.sin_addr.S_un.S_addr |= (100<<16);
addrCtrl.sin_addr.S_un.S_addr |= (ip<<24);
addrHost.sin_family = AF_INET;
addrHost.sin_port = htons(2000);
addrHost.sin_addr.S_un.S_addr = 0;
addrHost.sin_addr.S_un.S_addr = 192;
addrHost.sin_addr.S_un.S_addr |= (168<<8);
addrHost.sin_addr.S_un.S_addr |= (100<<16);
addrHost.sin_addr.S_un.S_addr |= ((100+ip)<<24);
sockerr = bind(sockComm,(SOCKADDR*)&addrHost, sizeof(SOCKADDR));
if(sockerr == SOCKET_ERROR)
{
// AfxMessageBox(_T("SOCKET初始化失败!"));
return -3;
}
err=connect(sockComm,(SOCKADDR*)&addrCtrl, sizeof(SOCKADDR));
if(err==-1)
{
return -4;
}
//不经历由socket缓冲区到系统缓冲区的拷贝而影响程序的性能:接收缓冲区为0
err=setsockopt(sockComm,SOL_SOCKET,SO_RCVBUF,(char *)&nZero,sizeof(int));
if(err !=0)
{
return -5;
}
setsockopt(sockComm,SOL_SOCKET,SO_RCVTIMEO, (char*)&max_timeout, sizeof(int));//超时时间
//非阻塞方式
err=ioctlsocket(sockComm,FIONBIO,(u_long *)&imode);
if(err == SOCKET_ERROR)
{
closesocket(sockComm);
WSACleanup();
return -6;
}
Sleep(1);
m_bNoExit = 1;
conn_timeout=0;
if(threadProcCtrlRecv==NULL)
{
threadProcCtrlRecv=AfxBeginThread(ProcCtrlRecv, NULL,THREAD_PRIORITY_TIME_CRITICAL);
//THREAD_PRIORITY_TIME_CRITICAL CRITICAL(最高) 如果进程优先级为realtime则调整为31,其它情况为15
}
回调函数数组
1、注册数组
void (*ptr_Callback[64])();
2、注册函数
void RegisterCallback(int i,void(*fn)());
{
ptr_Callback[i]=fn;
}
3、调用
(*ptr_Callback[i])();
应用:
void test_callback()
{
test_num+=1;
}
main
{
RegisterCallback(0,test_callback);
while(1)
{
if(....)
{
(*ptr_Callback[0])();
}
}
}
AfxBeginThread 传参数
1、变量参数
short *p_ip;//传进来的变量要一直有效,不能是临时变量
short ip_mc[MAX_CARD]={0};//全局变量
main
{
ip_mc[1]=1;
p_ip=&ip_mc[1];
threadProcCtrlRecv=AfxBeginThread(ProcCtrlRecv,p_ip,THREAD_PRIORITY_TIME_CRITICAL);
}
UINT __cdecl ProcCtrlRecv(LPVOID ip)
{
short mc=*(short *)(ip);
}
2、窗口指针
UINT Thread_DYNAMIC(LPVOID pParam);//线程声明
int Thread_key=0;
UINT Thread_DYNAMIC(LPVOID pParam)//线程定义
{
DLG_PT * p =(DLG_PT*)(pParam);//DLG_PT 本窗口类名
while(Thread_key)
{
if(((CComboBox*)p->GetDlgItem(IDC_CMB_PrfPt0))->GetCurSel()==0)//判断窗口控件状态
{
......
}
}
//delete p;//这个指针不用删除,没用new分配
//p=NULL;
return 0;
}
void DLG_PT::OnBnClickedBtnDynamic()//按钮创建线程
{
Thread_key=1;
CWinThread* pThread_DYNAMIC=AfxBeginThread(Thread_DYNAMIC,
this, //这里用this
THREAD_PRIORITY_NORMAL,
0,
0,
NULL);
}
volatile是一个类型描述符,要求编译器不要对其描述的对象作优化处理,对它的读写都需要从内存中访问。
回调函数获取对话框对象方法,请参阅一下链接:
C++静态成员函数访问非静态成员的几种方法
位操作
第n位置1
a=a | (1<<n);
置0
a=a & (~(1 << n));
a &=~( (1<<2) | (1<<3) );//将a的第2位、第3位清除
取反
采用或运算、异或运算。
位操作之异或运算的特点就是:两位相同的话,异或结果为0;不同为1。
思想:让要进行取反的位都和1进行异或,其他位则都和0进行异或。
例:将a的第7位和第9位取反。
int a=0x0023;
a ^=( (1<<7) | (1<<9) );
判断数的第i位是不是1
if ((x>> i) & 1)
if (((i_DI_word >> i) & 1) == Callback_edag[i])
16进制CString转10进制char
char OutBuf[8];
CString str16=NULL;
char pchar[4];
int getIndexOfSigns(char ch);
long hexToDec(char *source);
GetDlgItemText(IDC_EDIT_smcode,str16);
WideCharToMultiByte(CP_ACP, 0, str16.GetBuffer(), -1, pchar, 4, NULL, NULL);
OutBuf[1]=hexToDec(pchar);
int getIndexOfSigns(char ch)
{
if(ch >= '0' && ch <= '9')
{
return ch - '0';
}
if(ch >= 'A' && ch <='F')
{
return ch - 'A' + 10;
}
if(ch >= 'a' && ch <= 'f')
{
return ch - 'a' + 10;
}
return -1;
}
long hexToDec(char *source)
{
long sum = 0;
long t = 1;
int i, len;
len = strlen(source);
for(i=len-1; i>=0; i--)
{
sum += t * getIndexOfSigns(*(source + i)); //从低位开始,getIndexOfSigns函数返回其中一位字符对应的十进制数
t *= 16;
}
return sum;
}
```