开始学习(算是复习)网络编程了,第一个就是局域网的netbios协议编程。

  首先了解一下什么是netbios:IBM公司为PC-Network开发的一套网络标准。,NetBIOS最广泛的应用之一就是对NetBIOS用户扩展接口(NetBEUI,NetBIOS Extend User Interface)协议的使用。处在表示层与会话层之间,处于参考模型的高层。

  优点:短小精练; 良好的网络通信性能; 适合于适时性较高的小型LAN网络环境;

  缺点:是一种不可路由的协议;数据包无法跨网段传输。

NetBIOS程序的工作过程:

  首先,网络通信程序通过名字的标识区别于其他程序,并将名字注册到LANA中,获得合法的网络身份。

  之后,网络通信程序可以使用NetBIOS的数据报或会话服务与驻留在相同或不同主机中的其他应用程序进行通信。通信过程中,用户还可以使用一般命令服务对适配器进行管理和监测。

  最后,在通信结束后,通信程序需要删除已注册的名字并释放所占用的网络资源。

编程讲解:

  在Win32环境下,使用VS2012进行NetBIOS程序开发时, 需要用到nb30.h文件和netapi32.lib静态链接库。前者定义了NetBIOS的所有函数声明和常数定义,后者定义了NetBIOS应用。Ncb的结构在nb30.h文件中定义。Ncb结构的定义:Ncb有64个字符,分为14个域(或称为字段)和一个10字节的保留域。各字段这里就不详细了,另外一个博客有讲解。

编写NetBios命令函数的步骤:

    1. 定义函数原型。

    2. 申明NCB结构变量。

    3. 对该变量所有域清零。

    4. 根据命令填写相关域。

    5. 调用NetBios函数提交NCB结构。

    6. 判断NetBios函数返回值,作出相应处理。

    7. 从NCB中获取输出域。(根据具体命令)

简单的基于NetBios的对话编程,实现了建立会话过程,客户端向服务端发送数据,服务端接受数据并回复数据,客户端成功接受并无限递归(当然程序可以自己修改)。win32,vs2012,C++平台参考代码如下:

服务端代码参考:

 //服务端参考代码:
#include <windows.h>
#include <stdio.h>
#include <nb30.h>
#include "NetBioscmd.h"
#define MAX_SESSIONS 254
#define MAX_NAMES 254
#define MAX_BUFFER 1024
#define SERVER_NAME "server"
//
//Thread to give a simple service to client
//
DWORD WINAPI ServerThread(PVOID lpParam)
{
PNCB pncb =(PNCB)lpParam;
NCB ncb;
char buff[MAX_BUFFER],
Clientname[NCBNAMSZ+];
DWORD Bufferlen,retval =NRC_GOODRET;
FormatNetbiosName((char *)&pncb->ncb_callname,Clientname);
printf("a connect come\n");
ZeroMemory(buff,MAX_BUFFER);
Bufferlen =MAX_BUFFER; while (true)
{
retval =Recv(pncb->ncb_lana_num,pncb->ncb_lsn,buff,Bufferlen);
if(retval!=NRC_GOODRET)
return pncb->ncb_retcode;
printf("Massage from[%s]:%s\n",Clientname,buff);
ZeroMemory(buff,MAX_BUFFER);
Bufferlen =MAX_BUFFER;
strcpy(buff,"welcome you join the NetBIOS club.");
retval =Send(pncb->ncb_lana_num,pncb->ncb_lsn,buff,Bufferlen);
if(retval!=NRC_GOODRET)
return pncb->ncb_retcode;
} if(retval!=NRC_SCLOSED)
{
ZeroMemory(&ncb,sizeof(NCB));
ncb.ncb_command =NCBHANGUP;
ncb.ncb_lsn =pncb->ncb_lsn;
ncb.ncb_lana_num =pncb->ncb_lana_num;
if(Netbios(&ncb)!=NRC_GOODRET)
{
GlobalFree(pncb);
retval =ncb.ncb_retcode;
}
}
GlobalFree(pncb);
return NRC_GOODRET;
}
//
//Callback function to give a simple service to client, you can use it as another sever model
//
void CALLBACK listencallback(PNCB pncb)
{
//
//you also can write down code here to communicate to a client
//
}
//main function
int main(int argc, char* argv[])
{
HANDLE hEvent[],hThread;
NCB *pncb,
*workpncb;
DWORD ThreadId,
dwIndex;
UCHAR dwNum = ' ';
LANA_ENUM lenum;
int i;
if(LanaEnum(&lenum)!=NRC_GOODRET)
{
return ;
}
if(ResetAll(&lenum,(UCHAR)MAX_SESSIONS,(UCHAR)MAX_NAMES,false)!=NRC_GOODRET)
return ;
pncb = (NCB*)GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT,sizeof(NCB)*lenum.length);
for(i=;i<lenum.length;i++)
if((AddName((int)lenum.lana[i],SERVER_NAME,&dwNum))==NRC_GOODRET)
{printf("add name(%s) to lana[%d]\n",SERVER_NAME,lenum.lana[i]);
//printf("name(%s) have the name_num (%d)\n",SERVER_NAME,dwNum);
}
for(i=;i<lenum.length;i++)
{
hEvent[i]=CreateEvent(,TRUE,FALSE,);
if(Listen(&pncb[i],lenum.lana[i],SERVER_NAME,hEvent[i])==NRC_GOODRET)
printf("attempt to listen to lana[%d] succeed!\n",lenum.lana[i]);
}
printf("Server setup has been finished,now server begin to listen.\n");
while(true)
{
dwIndex=WaitForMultipleObjects(lenum.length,hEvent,FALSE,INFINITE);
if(dwIndex==WAIT_FAILED)
{
printf("WaitForMultipleObjects ERROR:%0xh\n",GetLastError());
break;
}
else
{
for(int i=;i<lenum.length;i++)
{
if(pncb[i].ncb_cmd_cplt!=NRC_PENDING)
{
workpncb = (NCB *)GlobalAlloc(GMEM_FIXED,sizeof(NCB));
memcpy(workpncb,&pncb[i],sizeof(NCB));
workpncb->ncb_event = ;
hThread=CreateThread(NULL,,ServerThread,(LPVOID)workpncb,,&ThreadId);
CloseHandle(hThread);
ResetEvent(hEvent[i]);
Listen(&pncb[i],lenum.lana[i],SERVER_NAME,hEvent[i]);
}
else
continue;
}
}
}
for(i=;i<lenum.lana[i];i++)
{
DelName(lenum.lana[i],SERVER_NAME);
CloseHandle(hEvent[i]);
}
GlobalFree(hEvent);
GlobalFree(pncb);
return ;
}

客户端代码参考:

 //客户端参考代码:
// client.cpp : Defines the entry point for the console application.
// #include <windows.h>
#include <stdio.h>
#include <nb30.h>
#include <winbase.h>
#include "NetBioscmd.h"
#define MAX_SESSIONS 254
#define MAX_NAMES 254
#define MAX_BUFFER 1024
#define MAX_DATAGRAM_SIZE 512
#define CLIENT_NAME "client"
#define SERVER_NAME "server"
//main fuction
int main(int argc, char* argv[])
{
HANDLE *hEvent;
NCB *pncb;
DWORD dwRet,
Bufferlen,dwIndex;
UCHAR *dwNum = NULL;
char Buff[MAX_BUFFER],
Servername[NCBNAMSZ+];
LANA_ENUM lenum;
int i;
if(LanaEnum(&lenum)!=NRC_GOODRET)
return ;
if(ResetAll(&lenum,(UCHAR)MAX_SESSIONS,(UCHAR)MAX_NAMES,false)!=NRC_GOODRET)
return ;
hEvent = (HANDLE*)GlobalAlloc(GMEM_FIXED,sizeof(HANDLE)*lenum.length); //分配内存
pncb = (NCB*)GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT,sizeof(NCB)*lenum.length);
dwNum = (UCHAR*)GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT,sizeof(UCHAR)*lenum.length);
for(i=;i<lenum.length;i++) //增加名字
if((AddName((int)lenum.lana[i],CLIENT_NAME,(UCHAR*)&dwNum[i]))==NRC_GOODRET)
{ printf("add name(%s) to lana[%d]\n",CLIENT_NAME,lenum.lana[i]);
//printf("name(%s) have the name_num (%d)\n",CLIENT_NAME,dwNum[i]);
}
for(i=;i<lenum.length;i++)// 连接
{
hEvent[i]=CreateEvent(,TRUE,FALSE,);
if((Connect(&pncb[i],lenum.lana[i],SERVER_NAME,CLIENT_NAME,hEvent[i]))==NRC_GOODRET)
printf("attempt to connect to lana[%d] succeed!\n",lenum.lana[i]);
} dwIndex = WaitForMultipleObjects(lenum.length,hEvent,FALSE,INFINITE); if(dwIndex == WAIT_FAILED)
printf("ERROR:WaitForMultipleObjects:%0xh\n",GetLastError());
else
{
for(int i=;i<lenum.length;i++)
{
if(i!=(int)dwIndex)
{
if(pncb[i].ncb_cmd_cplt==NRC_PENDING) //异步
Cancel(&pncb[i]);
else
Hangup(pncb[i].ncb_lana_num,pncb[i].ncb_lsn);
}
}
//printf("%i",(int)pncb[dwIndex].ncb_lana_num);
printf("a connect on[LANA %i] has been built!\n",(int)pncb[dwIndex].ncb_lana_num);
ZeroMemory(Buff,MAX_BUFFER);
Bufferlen = MAX_BUFFER;
while (TRUE)
{
strcpy(Buff,"I want to register to you.");
dwRet = Send(pncb[dwIndex].ncb_lana_num,pncb[dwIndex].ncb_lsn,Buff,Bufferlen);
if(dwRet!=NRC_GOODRET)
return pncb[dwIndex].ncb_retcode;
ZeroMemory(Buff,MAX_BUFFER);
dwRet=Recv(pncb[dwIndex].ncb_lana_num,pncb[dwIndex].ncb_lsn,Buff,Bufferlen);
if(dwRet!=NRC_GOODRET)
return pncb[dwIndex].ncb_retcode;
FormatNetbiosName((char *)&pncb->ncb_callname,Servername);
printf("Massage from[%s]:%s\n",Servername,Buff);
} Hangup(pncb[dwIndex].ncb_lana_num,pncb[dwIndex].ncb_lsn);
} for(i=;i<lenum.length;i++)
{
DelName(lenum.lana[i],CLIENT_NAME);
CloseHandle(hEvent[i]);
}
GlobalFree(hEvent);
GlobalFree(pncb);
return ;
}

其中需要一个头文件NetBIOScmd.h部分参考代码:

 //NetBIOScmd.h 部分参考代码:
//
//Get the status of local or remote adapter
//
#define MAX_DATAGRAM_SIZE 512
int Astatus(ADAPTER_STATUS *astat,int lana,char *name)
{
NCB ncb;
ZeroMemory(&ncb,sizeof(NCB));
ncb.ncb_command = NCBASTAT;
ncb.ncb_buffer = (PUCHAR)astat;
ncb.ncb_length = sizeof(ADAPTER_STATUS);
memset(&ncb.ncb_callname,' ',NCBNAMSZ);
strncpy((char *)&ncb.ncb_callname,name,strlen(name));
ncb.ncb_lana_num = lana;
if(Netbios(&ncb)!=NRC_GOODRET)
{
printf("Netbios NCBASTAT ERROR:%0xh\n",ncb.ncb_retcode);
return ncb.ncb_retcode;
}
return NRC_GOODRET;
}
//
//Get the machine's LANA NUM
//
int LanaEnum(LANA_ENUM *lenum)
{
NCB ncb;
ZeroMemory(&ncb,sizeof(NCB));
ncb.ncb_command = NCBENUM;
ncb.ncb_buffer = (PUCHAR)lenum;
ncb.ncb_length = sizeof(LANA_ENUM);
if(Netbios(&ncb)!=NRC_GOODRET)
{
printf("Netbios NEBENUM ERROR:%0xh\n",ncb.ncb_retcode);
return ncb.ncb_retcode;
}
return NRC_GOODRET;
}
//
//Reset All LANA NUM
//
int ResetAll(LANA_ENUM *lenum,UCHAR ucMaxSession,UCHAR unMaxName,BOOL bFirstname)
{
NCB ncb;
ZeroMemory(&ncb,sizeof(NCB));
ncb.ncb_command = NCBRESET;
ncb.ncb_callname[] = ucMaxSession;
ncb.ncb_callname[] = unMaxName;
ncb.ncb_callname[] = (UCHAR)bFirstname;
for(int i=;i<lenum->length;i++)
{
ncb.ncb_lana_num = lenum->lana[i];
if(Netbios(&ncb)!=NRC_GOODRET)
{
printf("Netbios NCBRESET[%d]ERROR:%0xh\n",ncb.ncb_lana_num,ncb.ncb_retcode);
return ncb.ncb_retcode;
}
}
return NRC_GOODRET;
}
//
//Add name of program
//
int AddName(int lana,char *name,UCHAR *num)
{
NCB ncb;
ZeroMemory(&ncb,sizeof(NCB));
ncb.ncb_command = NCBADDNAME;
ncb.ncb_lana_num = lana;
memset(ncb.ncb_name,' ',NCBNAMSZ);//add by jinhua
strncpy((char *)ncb.ncb_name,name,strlen(name));
if(Netbios(&ncb)!=NRC_GOODRET)
{
printf("Netbios NCBADDNAME[lana=%d;name=%s]ERROR:%0xh\n",lana,name,ncb.ncb_retcode);
return ncb.ncb_retcode;
}
*num = ncb.ncb_num;
return NRC_GOODRET;
}
//
//Cancel NetBios Command
//
int Cancel(PNCB pncb)
{
NCB ncb;
ZeroMemory(&ncb,sizeof(NCB));
ncb.ncb_command = NCBCANCEL;
ncb.ncb_buffer = (PUCHAR)pncb;
ncb.ncb_lana_num = pncb->ncb_lana_num;
if(Netbios(&ncb)!=NRC_GOODRET)
{
printf("Netbios NCBCANCEL ERROR:%0xh\n",ncb.ncb_retcode);
return ncb.ncb_retcode;
}
return NRC_GOODRET;
}
//
//Hangup Command
//
int Hangup(int lana,int lsn)
{
NCB ncb;
int retcode;
ZeroMemory(&ncb,sizeof(NCB));
ncb.ncb_command = NCBHANGUP;
ncb.ncb_lsn = lsn;
ncb.ncb_lana_num = lana;
retcode = Netbios(&ncb);
return retcode;
}
//
//Delete Name Command
//
int DelName(int lana,char *name)
{
NCB ncb;
ZeroMemory(&ncb,sizeof(NCB));
ncb.ncb_command = NCBDELNAME;
ncb.ncb_lana_num = lana;
//memset(ncb.ncb_name,' ',strlen(name));
memset(ncb.ncb_name,' ',NCBNAMSZ);//add by jinhua
strncpy((char *)ncb.ncb_name,name,strlen(name));
if(Netbios(&ncb) != NRC_GOODRET)
{
printf("Netbios NCBDELNAME [lana=%d;name=%s] ERROR:%0xh\n",lana,name,ncb.ncb_retcode);
return ncb.ncb_retcode;
}
return NRC_GOODRET;
}
//
//Add the group name to LANA number
//Retrun the name number for the registered name.
//
int AddGroupName(int lana,char *name,UCHAR *num)
{
NCB ncb;
ZeroMemory(&ncb,sizeof(NCB));
ncb.ncb_command = NCBADDGRNAME;
ncb.ncb_lana_num = lana;
memset(ncb.ncb_name,' ',NCBNAMSZ);
strncpy((char *)ncb.ncb_name,name,strlen(name));
if(Netbios(&ncb)!=NRC_GOODRET)
{
printf("Netbios NCBADDGRPNAME[lana=%d;name=%s] ERROR:%0xh\n",lana,name,ncb.ncb_retcode);
return ncb.ncb_retcode;
}
*num = ncb.ncb_num;
return NRC_GOODRET;
}
//
//function to realize NCBRECV
//
int Recv(int lana,int lsn,char *buffer,DWORD bufferlen)
{
NCB ncb;
ZeroMemory(&ncb,sizeof(NCB));
ncb.ncb_command =NCBRECV;
ncb.ncb_buffer =(PUCHAR)buffer;
ncb.ncb_length =(unsigned short)bufferlen;
ncb.ncb_lana_num =lana;
ncb.ncb_lsn =lsn;
if(Netbios(&ncb)!=NRC_GOODRET)
{
bufferlen = -;
printf("Netbios NCBRECV ERROR:%0xh.\n",ncb.ncb_retcode);
return ncb.ncb_retcode;
}
bufferlen = ncb.ncb_length;
return NRC_GOODRET;
}
//
//function to realize NCBSEND
//
int Send(int lana,int lsn,char *data,DWORD len)
{
NCB ncb;
int retcode;
ZeroMemory(&ncb,sizeof(NCB));
ncb.ncb_command =NCBSEND;
ncb.ncb_buffer =(PUCHAR)data;
ncb.ncb_length =(unsigned short)len;
ncb.ncb_lsn =lsn;
ncb.ncb_lana_num =lana;
retcode =Netbios(&ncb);
return retcode;
}
//
//covert the NetBIOS name from unprintable to printable
//
int FormatNetbiosName(char *nbname,char *outname)
{
int i;
strncpy(outname,nbname,NCBNAMSZ);
outname[NCBNAMSZ-] = '\0';
for(i=;i<NCBNAMSZ-;i++)
{
if(!((outname[i]>=)&&(outname[i]<=)))
outname[i] = '.';
}
return NRC_GOODRET;
}
//
//Send a broadcast datagram on the specified LANA number
//
int DatagramSendBC(int lana,int num,char *buffer,int buflen)
{
NCB ncb;
ZeroMemory(&ncb,sizeof(NCB));
ncb.ncb_command = NCBDGSENDBC;
ncb.ncb_lana_num = lana;
ncb.ncb_num = (UCHAR)num;
ncb.ncb_buffer = (PUCHAR)(buffer);
ncb.ncb_length = buflen;
if(Netbios(&ncb)!=NRC_GOODRET)
{
printf("Netbios NCBDGSENDBC ERROR:%0xh\n",ncb.ncb_retcode);
return ncb.ncb_retcode;
}
return NRC_GOODRET;
}
//
//receive a broadcast datagram on the specified LANA number from the registered name
//
int DatagramRecvBC(PNCB pncb,int lana,int num,char *buffer,int buflen,HANDLE hEvent)
{
ZeroMemory(pncb,sizeof(NCB));
ZeroMemory(buffer,sizeof(MAX_DATAGRAM_SIZE));
pncb->ncb_command = NCBDGRECVBC|ASYNCH;
pncb->ncb_lana_num = lana;
pncb->ncb_buffer = (PUCHAR)(buffer);
pncb->ncb_length = buflen;
pncb->ncb_event = hEvent;
if(Netbios(pncb)!=NRC_GOODRET)
{
printf("Netbios NCBDGRECVBC ERROR:%0xh\n",pncb->ncb_retcode);
return pncb->ncb_retcode;
}
return NRC_GOODRET;
}
//
//Send a directed datagram on the specified LANA number
//
int DatagramSend(int lana,int num,char *buffer,int buflen,char *Destname)
{
NCB ncb;
ZeroMemory(&ncb,sizeof(NCB));
ncb.ncb_command =NCBDGSEND;
ncb.ncb_lana_num =lana;
ncb.ncb_num =(UCHAR)num;
ncb.ncb_buffer =(PUCHAR)buffer;
ncb.ncb_length =buflen;
memset(ncb.ncb_name,' ',NCBNAMSZ);
strncpy((char *)ncb.ncb_callname,Destname,strlen(Destname));
if(Netbios(&ncb)!=NRC_GOODRET)
{
printf("Netbios NCBDGSEND ERROR:%0xh\n",ncb.ncb_retcode);
return ncb.ncb_retcode;
}
return NRC_GOODRET;
}
//
//Recieve a directed datagram on the specified LANA number from registered name
//
int DatagramRecv(PNCB pncb,int lana,int num,char *buffer,int buflen,HANDLE hEvent)
{
ZeroMemory(pncb,sizeof(NCB));
ZeroMemory(buffer,sizeof(MAX_DATAGRAM_SIZE));
pncb->ncb_command =NCBDGRECV|ASYNCH;
pncb->ncb_lana_num =lana;
pncb->ncb_num =(UCHAR)num;
pncb->ncb_buffer =(PUCHAR)buffer;
pncb->ncb_length =buflen;
pncb->ncb_event =hEvent;
if(Netbios(pncb)!=NRC_GOODRET)
{
printf("Netbios NCBDGRECV ERROR:%0xh\n",pncb->ncb_retcode);
return pncb->ncb_retcode;
}
return NRC_GOODRET;
}
//
//function to realize NCBLISTEN
//
int Listen(PNCB pncb,int lana,char *server,HANDLE hEvent)
{
pncb->ncb_command = NCBLISTEN|ASYNCH;
pncb->ncb_lana_num = lana;
memset(&pncb->ncb_name,' ',NCBNAMSZ);
strncpy((char *)&pncb->ncb_name,server,strlen(server));
memset(&pncb->ncb_callname,' ',NCBNAMSZ);
pncb->ncb_callname[] = '*';
pncb->ncb_event = hEvent;
//you also can use callback function to providw service to client
//pncb->ncb_post =listencallback;
if(Netbios(pncb)!=NRC_GOODRET)
{
printf("Netbios NCBLISTEN ERROR:%0xh.\n",pncb->ncb_retcode);
return pncb->ncb_retcode;
}
return NRC_GOODRET;
}
//
//fuction to realize NCBCALL
//
int Connect(PNCB pncb,int lana,char *server,char *client,HANDLE hEvent)
{
pncb->ncb_command =NCBCALL|ASYNCH;
pncb->ncb_lana_num =lana;
memset(&pncb->ncb_name,' ',NCBNAMSZ);
strncpy((char *)&pncb->ncb_name,client,strlen(client));
memset(&pncb->ncb_callname,' ',NCBNAMSZ);
strncpy((char *)&pncb->ncb_callname,server,strlen(server));
pncb->ncb_event =hEvent;
if(Netbios(pncb)!=NRC_GOODRET)
{
printf("ERROR:Netbios:NCBCONNECT.%0xh\n",pncb->ncb_retcode);
return pncb->ncb_retcode;
}
return NRC_GOODRET;
}

这两天看的netbios,简单整理了一下,分享给园友,有问题请指正,谢谢。

NetBios网络基础及编程的更多相关文章

  1. 网络基础:NetBIOS

    网络基础小补. 利用 NetBIOS 名称与其他计算机通信 网络中的计算机之间必须知道IP地址后才能相互通信.但对人来说IP难以记忆,NetBIOS计算机名称比较容易记忆.当计算机使用 NetBIOS ...

  2. JAVA基础知识之网络编程——-网络基础(Java的http get和post请求,多线程下载)

    本文主要介绍java.net下为网络编程提供的一些基础包,InetAddress代表一个IP协议对象,可以用来获取IP地址,Host name之类的信息.URL和URLConnect可以用来访问web ...

  3. Java 网络编程(一) 网络基础知识

    链接地址:http://www.cnblogs.com/mengdd/archive/2013/03/09/2951826.html 网络基础知识 网络编程的目的:直接或间接地通过网络协议与其他计算机 ...

  4. Python3 与 C# 网络编程之~ 网络基础篇

    最新版本查看:https://www.cnblogs.com/dotnetcrazy/p/9919202.html 入门篇 官方文档:https://docs.python.org/3/library ...

  5. 网络编程—网络基础概览、socket,TCP/UDP协议

    网络基础概览 socket概览 socket模块—TCP/UDP的实现 TCP/UDP总结 网络基础概览 osi七层协议各层主要的协议 # 物理层传输电信号1010101010 # 数据链路层,以太网 ...

  6. Linux应用程序设计之网络基础编程

    1.TCP/IP协议概述 1.1.OSI参考模型及TCP/IP参考模型 OSI协议参考模型是基于国际标准化组织(ISO)的建议发展起来的,从上到下工分为7层:应用层,表示层,会话层,传输层,网络层,数 ...

  7. 网络编程基础:网络基础之网络协议、socket模块

    操作系统(简称OS)基础: 应用软件不能直接操作硬件,能直接操作硬件的只有操作系统:所以,应用软件可以通过操作系统来间接操作硬件 网络基础之网络协议: 网络通讯原理: 连接两台计算机之间的Intern ...

  8. python基础(29):网络编程(软件开发架构、网络基础、套接字初使用)

    1. 软件开发架构 我们了解的程序之间通讯的应用可分为两种: 第一种是应用类:qq.微信.百度网盘.腾讯视频这一类是属于需要安装的桌面应用. 第二种是web类:比如百度.知乎.博客园等使用浏览器访问就 ...

  9. Java Socket编程----网络基础

    详见:https://www.cnblogs.com/rocomp/p/4790340.html Java最初是作为网络编程语言出现的,其对网络提供了高度的支持,使得客户端和服务器的沟通变成了现实,而 ...

随机推荐

  1. 第k大的数,前k大的数

    1.排序后去出前k个,o(n*log(n))    如果k<log(n),可以考虑直接选择排序,因为只需要执行找到第k个就可以结束 o(n*k) 2.o(nlog(k))快排把数分为了两个部分, ...

  2. MYSQL性能调优: 对聚簇索引和非聚簇索引的认识

    聚簇索引是对磁盘上实际数据重新组织以按指定的一个或多个列的值排序的算法.特点是存储数据的顺序和索引顺序一致.一般情况下主键会默认创建聚簇索引,且一张表只允许存在一个聚簇索引. 在<数据库原理&g ...

  3. Entity Framework 异常档案

    1.异常 The model backing the 'DBContext' context has changed since the database was created.Consider u ...

  4. js获取页面传过来的参数

    //接收页面传过来的值 //RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i" ...

  5. SQL优化法则小记

    SQL优化技巧 1.选择最有效率的表名顺序(只在基于规则的优化器中有效): oracle的解析器按照从右到左的顺序处理 from 子句中的表名,from子句中写在最后的表(基础表 driving ta ...

  6. C#删除文件和文件夹到回收站

    首先对项目添加名为Microsoft.VisualBasic.dll的引用,然后添加命名空间using Microsoft.VisualBasic.FileIO;usingSystem;namespa ...

  7. 虚拟机Linux----Ubuntu1204----root登录设置

    说明:装好的ubuntu12.04登录时,默认是看不到root用户的,需要设置一下. 1.先用普通用户登录,打开终端,切换为root用户,如下: su root 2.修改 sudo gedit /et ...

  8. 《精解Windows 10》

    <精解Windows 10>全面深入讲解Windows 10操作系统的使用方法.本书共计14章内容.第一章简述Windows 10操作系统的一些变革:第二章介绍Modern 2.0界面的体 ...

  9. codeforces 721C C. Journey(dp)

    题目链接: C. Journey time limit per test 3 seconds memory limit per test 256 megabytes input standard in ...

  10. TDD in Expert Python Programmin

    Test-Driven Development PrinciplesTDD consists of writing test cases that cover a desired feature, t ...