开始学习(算是复习)网络编程了,第一个就是局域网的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. XML学习总结(一)——XML介绍

    一.XML概念 Extensible Markup Language,翻译过来为可扩展标记语言.Xml技术是w3c组织发布的,目前推荐遵循的是W3C组织于2000发布的XML1.0规范. 二.学习XM ...

  2. 网络编程1--毕向东java基础教程视频学习笔记

    目录: 01 网络编程概述1 02 网络编程概述2 03网络编程 网络模型 04网络编程 IP地址 05网络编程 TCP和UDP 06网络编程 Socket 07网络编程 UDP发送端 01 网络编程 ...

  3. Effective Java 11 Override clone judiciously

    Principles If you override the clone method in a nonfinal class, you should return an object obtaine ...

  4. APP原型设计工具,哪家强?转自知乎

    著作权归作者所有. 商业转载请联系作者获得授权,非商业转载请注明出处. 作者:李志超 链接:http://www.zhihu.com/question/20403141/answer/25329730 ...

  5. 10_放置街灯(Placing Lampposts,UVa 10859)

    问题来源:刘汝佳<算法竞赛入门经典--训练指南> P70 例题30: 问题描述:有给你一个n个点m条边(m<n<=1000)的无向无环图,在尽量少的节点上放灯,使得所有边都被照 ...

  6. python 练习多级菜单思路

    只写了一个zj的三级菜单,后面的功能没写 #-*- coding :utf-8 -*- print """ 你可以输入省份然后根据市县输入 ""&qu ...

  7. jquery实现点击radio,当选中‘其它’时,显示后面输入框;否则隐藏

    有时候会遇到这么一个很简单的功能: jquery实现点击radio,当选中‘其它’时,显示后面输入框:否则隐藏 html代码: <div> <input type="rad ...

  8. 转: Github访问慢解决办法

    from: https://yq.aliyun.com/articles/36744 Github访问慢解决办法   zxiaofan 2016-04-20 17:25:00 浏览2156 评论0 摘 ...

  9. 斯坦福大学 iOS 7应用开发 ppt

    上网的找了很久都不全,最后发现原来网易那个视频下面就有完整的PPT..

  10. 开坑,Unix环境高级编程,转行之路又得缓缓了

    不要问我基础,我用了近6年的Linux系统,最早的版本可以追溯到Ubuntu 8.04,常用的命令 VIM基本上是没压力,遇到问题google 配置环境变量 网络环境也不在话下, C语法基本熟练,过去 ...