【vc】14_网络编程_socket编程

1、计算机网络基本知识

  最简单的网络程序如图:

  提示:IP地址就相当于一个公司的总机号码,端口号就相当于分机号码。在打电话时,拨通总机后,还需要转到分机上。

(1)协议

    ·为进行网络中的数据交换(通信)而建立的规则、标准或约定(=语义+语法+规则);

    ·不同层具有各自不同的协议;

(2)网路的状况

    ·多种通信媒介---有线、无线···

    ·不同种类的设备---通用、专用···

    ·不同的操作系统---UNIX、Windows···

    ·不同的应用环境---固定、移动···

    ·不同的业务种类---分时、交互、实时···

    ·宝贵的投资和积累---有形、无形···

    ·用户业务的延续性---不允许出现大的跌岩起伏;

   他们互相交织,形成了非常复杂的系统应用环境。    

(3)ISO/OSI七层参考模型

    ·物理层:提供二进制传输,确定在通信新到上如何传输比特流;

    ·数据链路层:提供介质访问,加强物理层的传输功能,建立一条无差错的传输线路;

    ·网络层:提供IP寻址和路由(网络上数据可以经由多条线路到达目的地,网络层负责找出最佳的传输线路);

    ·传输层:为源端主机到目的端主机提供可靠的数据传输服务,隔离网络的上下层协议,使得网络应用与下层协议无关;

    ·会话层:在两个相互通信的应用进程之间建立、组织和协调其相互之间的通信;

    ·表示层:处理被传送数据的表示问题,即信息的语法和语义;如有必要,可使用一种通用的数据表四格式,在多种数据表示之间进行转换。例如在日期、货币、数值等本地数据表示格式和标准数据表示格式之间进行转换,还有数据的加解密、压缩和解压缩等;

    ·应用层:为用户的网络应用程序提供网络通信的服务;

   注意:在进行一次网络通信时,每一层为本次通信提供本次的服务(通信实体的对等体之间不允许直接通信);

      各层之间是严格单向依赖;

      上层使用下层提供的服务---Service user;

      下层向上层提供服务---Service provider;

见图:::附图片:

  应用层、传输层、网络层各使用的协议

    应用层:Telnet(远程登录协议)、FTP(文件传输协议)、HTTP(超文本传输协议)、DNS(域名服务)、SMTP(简单邮件传输协议)、POP3(邮局协议)等;

    传输层:TCP(传输控制协议)、UDP(用户数据报协议);

    网络层:网际协议IP、Internet互联网控制报文协议ICMP、Internet组管理协议IGMP;

(4)数据封装

    ·一台计算机要想另一台计算机发送数据,首先必须将该数据打包,打包的过程成为封装(即:在数据前面加上特定的协议头部);

    ·PDU(协议数据单元):对等层协议之间交换的信息单元的统称;

    ·头部含有的数据中含有王城数据传输所需的控制信息;

(5)TCP/IP模型

(6)端口

    ·传输层提供进程(活动的应用程序)通信的能力;为了标识通信实体中进行通信的进程(应用程序),TCP/IP协议提出了协议端口(protocol port,简称端口)的概念;

    ·端口用一个整数型标识符来飙表示,即端口号;端口号跟协议相关,TCP/IP传输层的两个协议TCP和UDP是完全独立的两个软件模块,因此各自的端口号也相互独立;

    ·我们在编写网络应用程序时,要为程序指定1024以上的端口号;1024以下端口号保留给预定义的服务;

(7)套接字的引入

    ·套接字存在于通信区域中;通信区域也叫地址族,主要用于将通过套接字通信的进程的共有特性综合在一起;

    ·套接字通常只与同一区域的套接字交换数据(也有可能跨区域通信,但这只在执行了某种转换进程后才能实现);

    ·Windows Sockets只支持一个通信区域:网际域(AF_INET),这个域被使用网际协议簇通信的进程使用;

(8)网络字节顺序

    ·不同的计算机存放多字节的顺序不同;

    ·基于Inter的CPU,采用的是低位先存。为保证数据的正确性,在网络协议中需要指定网络字节顺序,TCP/IP协议使用16位整数和32位整数的高位先存格式;

    ·网络中不同主机间进行通信时,要同一采用网络字节顺序

(9)客户机/服务器模式

图片来自:http://pic002.cnblogs.com/images/2012/387401/2012111509190090.jpg

  客户机/服务器在操作过程中采用主动请求的方式,首先服务器方要先启动,并根据请求提供相应的服务:

    ①打开一个通信通道并告知本地主机,他愿意在某一地址可端口上接收客户请求;

    ②等待客户请求到达该端口;

    ③接收到重复服务请求,处理请求并发送应答信息。接收到并发起服务请求,要激活一个新的进程(或线程)来处理这个客户请求。新进程(或线程)处理此客户请求,并不需要对其他请求做出应答。服务完成后,关闭此新进程与客户的通信链接,并终止;

    ④返回第二步,等待另一客户请求;

    ⑤关闭服务器;

  客户方:

    ①打开一个通信通道,并连接到服务器所在主机的特定端口;

    ②想服务器发送服务请求报文,等待并接收应答;继续提出请求;

    ③请求结束后关闭通信通道并终止;

2、Windows Sockets的实现

  Socket是连接应用程序与网络驱动程序的桥梁,Socket在应用程序中创建,通过绑定操作与驱动程序建立关系。此后,应用程序送给Socket的数据,由Socket交给驱动程序向网络上发送出去。计算机从网络上收到与该Socket绑定的IP地址和端口号相关的数据后,由驱动程序交给Socket。应用程序便可从该Socket中提取接收到的数据。

(1)套接字的类型

    ·流式套接字(SOCK_STREAM)

       提供面向连接、可靠的数据传输服务,数据乌差错、无重复的发送,且按接发送顺序接收;SOCK_STREAM是基于TCP协议实现的;

    ·数据报式套接字(SOCK_DGRAM)

       提供无连接服务;数据包以独立包形式发送,不提供无差错保证,数据可能丢失和重复,并且接收顺序混乱;SOCK_DGRAM是基于 UDP协议实现的;

    ·原始套接字(SOCK_RAW)

(2)基于TCP(面向连接)的Socket编程

  基于基于TCP(面向连接)的Socket编程的服务端程序流程如下:

    ①创建套接字(socket);

    ②将套接字绑定到一个本地地址和端口上(bind);(解释:告诉本地主机它打算在哪个IP地址和哪个端口上等待客户请求)

    ③将套接字设为监听模式,准备接收客户请求(listen);

    ④等待客户请求到来;当请求到来后,接受连接请求,返回一个新的对应于此连接的套接字(accept);

    ⑤用返回的套接字和客户端进行通信(send/recv);

    ⑥返回,等待另一个客户请求;

    ⑦关闭套接字;

  基于基于TCP(面向连接)的Socket编程的客户端程序流程如下:

    ①创建套接字(socket);

    ②向服务器发出连接请求(connect);

    ③和服务器端进行通信(send/recv);

    ④关闭套接字;

  在服务器端,当调用accept函数时,程序就会等待,等待客户端调用connect函数发出连接请求,然后服务器端接收该请求,于是双方就建立了连接,之后,服务器端和客户端就可以利用send和recv函数进行通信了。

(3)基于UDP(面向无连接)的socket编程

  接收端(服务器端):先启动的一端;发送端(客户端):发送数据的一端;

  接收端程序的编写:

    ①创建套接字(socket);

    ②将套接字绑定到一个本地地址和端口上(bind);(解释:接收端告诉本地主机,它是在哪个地址和端口上等待数据的到来)

    ③等待接收数据(recvfrom);

    ④关闭套接字;

  客户端程序的编写:

    ①创建套接字(socket);

    ②向服务器发送数据(sendto);

    ③关闭套接字;

提示:套接字表示了通信的端点;利用套接字通信与利用电话机通信是一样的,套接字相当于电话机,IP地址相当于总机号码,端口号相当于分机。

3、相关函数

  (1)WSAStartup函数

int WSAStartup(
  WORD wVersionRequested,  //指定准备加载的Winsock库的版本;
  LPWSADATA lpWSAData       //是一个返回值,指向WSADATA结构的指针
);
//lpWSAdata:这是一个返回值,指向WSADATA结构的指针,WSAStartup函数用其加载的库版本有关的信息填在这个结构中;

    ·功能:①加载套接字库;

        ②进行套接字库的版本的协商(确定将使用的socket版本);

    ·对于每一个WSAStartup函数的成功调用(即成功加载WinSock动态库后),在最后对应一个WASCleanUp调用,来释放该程序占用的资源,终止对WinSock动态库的使用。

typedef struct WSAData {
  WORD                  wVersion;
  WORD                  wHighVersion;
  char                  szDescription[WSADESCRIPTION_LEN+1];
  char                  szSystemStatus[WSASYS_STATUS_LEN+1];
  unsigned short        iMaxSockets;
  unsigned short        iMaxUdpDg;
  char FAR *            lpVendorInfo;
} WSADATA, *LPWSADATA; 

    ·WSAStartup函数把WSADate结构中的第一个字段wVersion设置为打算使用的Winsock版本,wHighVersion字段容纳的是现有的Winsock库的最高版本;

    ·注意:这两个字段中,高位字节代表的是Winsock副版本,而低字节代表的则是Winsock朱版本;

  (2)socket函数

SOCKET socket(
  int af,       //指定地址簇,对于TCP/IP协议的套接字,它只能是AF_INET(或PF_INET);
  int type,     //指定socket类型(SOCK_STREAM、SOCK_DGRAM)
  int protocol  //与特定的地址家族相关的协议;
);

    ·如果socket函数调用成功,它就会返回一个新的SOCKET数据类型的套接字描述符;调用失败,返回一个INVALID_SOCKET值,错误信息可以通过WSAGetLastError函数返回。

  (3)bind函数

int bind(
  SOCKET s,   //指定要绑定的套接字;
  const struct sockaddr FAR *name,  //指向sockaddr结构的指针变量,指定了该套接字的本地地址信息;
  int namelen    //指定sockaddr地址结构的长度;
);

    ·name:指定了该套接字的本地地址信息;指向sockaddr结构的指针变量,由于该地址结构是为所有的地址家族准备的,这个结构可能随所使用的网络协议不同而不同,故:第三个参数(namelen)指定改地址结构的长度;

    ·功能:创建套接字成功之后,将该套接字绑定到本地的某个地址和端口上;

sockaddr结构定义如下:

struct sockaddr {
  u_short    sa_family;
  char       sa_data[14];
};  

    ·sockaddr结构的第一个字段(sa_family)指定地址家族,对于TCP/IP协议的套接字,必须设置为AF_INET;
    ·第二个地段(sa_data)仅仅是表示要求一块内存分配区,起到占用的作用,该区域中指定与协议相关的具体地址信息;

  ·注意:由于实际要求的只是内存去,所以对于不同的协议家族,用不同的结构来替代sockaddr。处理sa_family外,sockaddr是按网络字节顺序表示的。

      **在基于TCP/IP的socket编辑过程中,可以用sockaddr_in结构替换sockaddr以方便我们填写地址信息**。

sockaddr_in结构体的定义如下:

struct sockaddr_in{
 short sin_family;         //表示地址族;(对于IP地址,改变量一直是AF_INET)
 unsigned short sin_port; //指定将要分配给套接字的端口;
 IN_ADDR sin_addr;      //给出套接字的主机IP地址;
 char sin_zero[8];};      //填充数(使sockaddr_in和sockaddr长度一样);

    ·sockaddr_in结构中sin_addr成员的类型是in_addr,该结构的定义如下所示:

struct in_addr {
  union {
          struct { u_char s_b1,s_b2,s_b3,s_b4; }   S_un_b;
          struct { u_short s_w1,s_w2; }            S_un_w;
          u_long                                   S_addr;
  } S_un;
};

  ·提示:in_addr结构实际上是一个联合,通常利用这个结构将一个点分十进制格式的IP地址转换为u_long类型,并将结果赋给成员S_addr。

  (4)inet_addrinet_intoa函数

unsigned long inet_addr(  const char   FAR *cp  );

    ·inet_addr函数需要一个字符串作为其参数,该字符串指定了以点分十进制格式表示的IP地址(如192.168.0.16);而且inet_addr函数会返回一个适合分配给S_addr的u_long类型的数值;

char FAR * inet_ntoa(  struct   in_addr in  );

    ·inet_ntoa函数完成与inet_addr相反的转换,它就收一个i额in_addr结构体类型的参数并返回一个以点分十进制格式表示的IP地址字符串;

  (5)listen函数

int listen(
  SOCKET s,   // 套接字描述符;
  int backlog // 等待**连接队列**的最大长度;
);

    ·作用:将指定的套接字设置为监听模式;

  (6)accept函数

SOCKET accept(
  SOCKET s,   //套接字描述符,该套接字已经通过listen函数将其设置为监听状态;
  struct sockaddr FAR *addr,
  int FAR *addrlen  //是一个返回值,指向一个整型的指针,返回包含地址信息的长度;
);

    ·功能:接受客户端发出的连接请求;

    ·addr参数:指向一个缓冲区的指针,该缓冲区用来接收连接实体的地址,也就是当客户端服务器发起连接,服务器接受这个连接时,保存发起连接的这个客户端的IP地址信息和端口信息;

  (7)send函数

int send(
  SOCKET s,             //一个已经建立连接的套接字;
  const char FAR *buf,  //buf指向一个缓冲区,该缓冲区包含将要传递的数据;
  int len,              //len是缓冲区的长度;
  int flags             //flogs:设定的值将影响函数的行为,一般将器设置为0即可;
);

    ·功能:通过一个已建立连接的套接字发送数据;

  (8)recv函数

int recv(
  SOCKET s,       //s:建立连接后准备接收数据的那个套接字;
  char FAR *buf,  //buf:指向缓冲区的指针,用来保存接收的数据;
  int len,        //len:缓冲区的长度;
  int flags       //同send的flags;
);

    ·功能:从一个已连接的套接字接收数据;

  (9)connect

int connect(
  SOCKET s,                        //s:即将在其上建立连接的那个套接字;
  const struct sockaddr FAR *name, //name:设定连接的服务器地址信息;
  int namelen                      //namelen:指定服务器端地址的长度;
);

    ·功能:将与一个特定的套接字建立连接;

  (10)recvfrom

int recvfrom(
  SOCKET s,                   //s:准备接收数据的套接字;
  char FAR* buf,              //buf:指向缓冲区的指针,该缓冲区用来接收数据;
  int len,                    //len:缓冲区长度;
  int flags,                  //不解释
  struct sockaddr FAR *from,  //from:是一个指向地址结构的指针,主要是用来接收发送数据方的地址信息;
  int FAR *fromlen            //整型指针,且是一个in/out类型的参数;
);

    ·功能:将接收一个数据报信息并保存源地址;

    ·fromlen:是一个in/out类型的参数,表明在调用前需要给它指定一个初始值,当函数调用之后,会通过这个参数返回一个值,该返回值是底黑字结构的大小;

  (11)sendto

int sendto(
  SOCKET s,
  const char FAR *buf,
  int len,
  int flags,
  const struct sockaddr FAR *to,  //可选的指针,指定目标套接字的地址;
  int tolen                       //tolen:是参数to中指定的地址的长度;
);

    ·功能:将向一个特定的目的方发送数据;

  (12)htonshtonl 函数

u_short htons(
  u_short hostshort  //hostshort:是一个以主机字节顺序表示的16为数值;
);

    ·功能:(Windows Sockets的htons函数)将把一个u_short类型的值从主机字节顺序转换为TCP/IP网络字节顺序;

u_long htonl(
  u_long hostlong  //是一个以主机字节顺序表示的32位数值;
);

    ·功能:将把一个u_long类型的值从主机字节顺序转换为TCP/IP网络字节顺序;

4、基于TCP的网络应用程序的编写

  服务器端程序:

#include <stdio.h>
#include <Winsock2.h>

void main()
{
    //加载套接字库
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;

    wVersionRequested = MAKEWORD( 1, 1 );  //MAKEWORD宏创建一个包含一个请求版本号的WORD值;
                      //MAKEWORD(x,y)宏(x是高位字节, y是低位字节)可以方便的获取wVersionRequested的正确值;
    err = WSAStartup( wVersionRequested, &wsaData );

    if ( err != 0 ) {
        return;
    }

    if ( LOBYTE( wsaData.wVersion ) != 1 ||
        HIBYTE( wsaData.wVersion ) != 1 ) {
        WSACleanup( );
        return;
    }
    //①创建用于监听的套接字
    SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);

    SOCKADDR_IN addrSrv;
    addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(6000);

    bind(sockSrv, (sockaddr*)&addrSrv, sizeof(SOCKADDR) );    //②绑定套接字

    listen(sockSrv, 5);    //③将套接字设为监听模式,准备就收客户请求

    SOCKADDR_IN addrClient;
    int len = sizeof(SOCKADDR);

    while(1)
    {
        SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &len);    //④等待客户请求到来
        char sendBuf[100];
        sprintf(sendBuf, "welcome %s to http://www.cnblog.com.aze-003", inet_ntoa(addrClient.sin_addr));

        send( sockConn, sendBuf, strlen(sendBuf)+1, 0);    //发送数据 注意:“+1”:表示增加1个“\0”结尾标志;

        char recvBuf[100];
        recv( sockConn, recvBuf, 100, 0);    //接收数据
        printf("%s\n", recvBuf);    //打印接收的数据

        closesocket(sockConn);    //⑦关闭套接字
    }
}
/*    ④等待客户请求到来;当请求到来后,接收连接请求,返回一个新的对应于此次连接的套接字(accept)
    ⑤用返回的套接字和客户端进行连接通信(send/recv);
    ⑥返回,等待另一客户请求;
    注意:在调用accept函数前,必须为它的第三个参数赋予一个初始值,即:SOCKADDR_IN结构体的长度;

       进入循环,首先调用accept函数等待并接收客户的连接请求,其中第一个参数是处于监听状态的套接字;
    第二个参数利用addrClient变量接收客户端的地址信息。当客户端连接请求到来时,该函数接受该请求,建
    立连接,同时它将返回一个相对于当前这个新连接的一个套接字描述符,保存于sockConn变量中,然后利用
    这个套i蛾子就可以与客户端进行通信了,而我们先前的套接字仍然继续监听客户端的连接请求;
  */

TCP_Srv

  客户端程序:

#include <stdio.h>
#include <Winsock2.h>

void main()
{
    //加载套接字库
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;

    wVersionRequested = MAKEWORD( 1, 1 );

    err = WSAStartup( wVersionRequested, &wsaData );

    if ( err != 0 ) {
        return;
    }

    if ( LOBYTE( wsaData.wVersion ) != 1 ||
        HIBYTE( wsaData.wVersion ) != 1 ) {
        WSACleanup( );
        return;
    }
    //①创建套接字
    SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);

    SOCKADDR_IN addrSrv;
    addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(6000);

    //②向服务器发出连接请求
    connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));    

    //③和服务器进行通信(send/recv)
    char recvBuf[100];
    recv(sockClient, recvBuf, 100, 0);    //接收数据
    printf("%s\n", recvBuf);

    send(sockClient, "this is lisi", strlen("this is lisi")+1, 0);    //发送数据

    closesocket(sockClient);    //④关闭套接字

    WSACleanup();
}

TCP_Client

5、基于UDP的网络应用程序的编写

  服务器端程序: 

//UDP_Srv.cpp
#include <stdio.h>
#include <Winsock2.h>

void main()
{
    //加载套接字库
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;

    wVersionRequested = MAKEWORD( 1, 1 );

    err = WSAStartup( wVersionRequested, &wsaData );

    if ( err != 0 ) {
        return;
    }

    if ( LOBYTE( wsaData.wVersion ) != 1 ||
        HIBYTE( wsaData.wVersion ) != 1 ) {
        WSACleanup( );
        return;
    }
    //①创建套接字
    SOCKET sockSrv = socket( AF_INET, SOCK_DGRAM, 0);
    SOCKADDR_IN addrSrv;
    addrSrv.sin_addr.S_un.S_addr = htonl(ADDR_ANY);
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(6000);
    //②绑定套接字
    bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
    //③等待并接收数据 (UDP服务器就是一个接收端)
    SOCKADDR_IN addrClient;
    int len = sizeof(SOCKADDR);
    char recvBuf[100];
    recvfrom(sockSrv, recvBuf, 100, 0, (SOCKADDR*)&addrClient, &len);
    printf("%s\n", recvBuf);

    closesocket(sockSrv);    //④关闭套接字
    WSACleanup();
}

UDP_Srv.cpp

  客户端程序:

//UDP_Client.cpp
#include<WINSOCK2.H>
#include<STDIO.H>

void main()
{
    //加载套接字库
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;

    wVersionRequested = MAKEWORD( 1, 1 );

    err = WSAStartup( wVersionRequested, &wsaData );

    if ( err != 0 ) {
        return;
    }

    if ( LOBYTE( wsaData.wVersion ) != 1 ||
        HIBYTE( wsaData.wVersion ) != 1 ) {
        WSACleanup( );
        return;
    }
    //创建套接字
    SOCKET sockClient = socket(AF_INET, SOCK_DGRAM, 0);
    SOCKADDR_IN sockSrv;
    sockSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    sockSrv.sin_family = AF_INET;
    sockSrv.sin_port = htons(6000);
    //发送数据
    sendto(sockClient, "hello!", strlen("hello!")+1, 0, (SOCKADDR*)&sockSrv, sizeof(SOCKADDR));
    //关闭套接字
    closesocket(sockClient);
    WSACleanup();

}

UDP_Client.cpp

2014-08-14  

23:56:21

【vc】14_网络编程_socket编程,布布扣,bubuko.com

时间: 2024-10-11 16:25:21

【vc】14_网络编程_socket编程的相关文章

NetBios网络基础及编程

开始学习(算是复习)网络编程了,第一个就是局域网的netbios协议编程. 首先了解一下什么是netbios:IBM公司为PC-Network开发的一套网络标准.,NetBIOS最广泛的应用之一就是对NetBIOS用户扩展接口(NetBEUI,NetBIOS Extend User Interface)协议的使用.处在表示层与会话层之间,处于参考模型的高层. 优点:短小精练; 良好的网络通信性能; 适合于适时性较高的小型LAN网络环境; 缺点:是一种不可路由的协议:数据包无法跨网段传输. Net

网络分流器-网络分流器-多核编程的几个难题及其应对策略

网络分流器-网络分流器-多核编程的几个难题及其应对策略! 戎腾网络: 随着多核CPU的出世,多核编程方面的问题将摆上了程序员的日程,有许多老的程序员以为早就有多CPU的机器,业界在多CPU机器上的编程已经积累了很多经验,多核CPU上的编程应该差不多,只要借鉴以前的多任务编程.并行编程和并行算法方面的经验就足够了. 我想说的是,像涉及到网络分流器采集器功能的多核处理板业内统称为业务处理板,而多核机器和以前的多CPU机器有很大的不同,以前的多CPU机器都是用在特定领域,比如服务器,或者一些可以进行大

第五章 网络与并发编程

第五章 网络与并发编程 1.网络编程 1.1 网络编程定义 基于多台机器之间的通信需要基于网络编程 1.2 web程序的架构 C/S架构:client(客户端)/server(服务端) 所有需要安装的.exe文件都属于客户端 B/S架构:breowser(浏览器)/server(服务端) 所有能被网页访问的网络都是B/S架构 C/S和B/S之间的关系:所有的B/S架构都需要一个浏览器才能访问,浏览器是一个软件,相当于客户端,多有的B/S架构也都是C/S架构的,浏览器(breowser)是特殊的客

VC++ TCP网络控制台程序

在Windows7系统下,采用工具为VS2008,Win32控制台应用程序,编写一个基于TCP的Client/Server网络程序. 1.服务器端代码 #include <WinSock2.h> #include <stdio.h> //VS2012创建的MFC Win32控制台应用程序中,此处默认包含的是#include "stdafx.h",其中stdio.h头文件已经被包含进stdafx.h中了,不再需要重复包含 #define SERVERPORT 60

VC++ UDP网络控制台程序

 采用的是VC2008,控制台应用程序,使用UDP编写. 1.服务端代码 //UDPServer.cpp #include <WinSock2.h> #include <stdio.h> #define SERVERPORT 6000 //服务端口号 #pragma comment(lib, "WS2_32.lib") int main(int argc, char *argv[]) { //加载套接字库 WORD wVersionRequested; WSAD

MFC之窗口修改工具栏编程状态栏编程程序启动画面

1窗口外观的修改 (1)修改在CMainFrame::preCreateWindow(CREATESTRUCT& cs) 修改标题:cs.style&=FWS_ADDTOTITLE; cs.lpszNamw="new title"; (2)窗口创建之后修改外观 在CMainframe::Create()中调用SetWindowLong(HWND hwnd,.....)根据参数修改指定的项 所有从CWnd派生的类都是窗口类在这些窗口类中都有一个公有的成员变量保存了和着个窗

代写MATLAB编程- MATLAB编程代写Design a pushdown automata (PDA)

Design a pushdown automata (PDA)1.Consider the language of all binary strings that start and end with the same symbol. (a) Write the production rules of a grammar for this language. Show some derivations to test that your grammar is correct. (b) Desi

全新编程模式---站立编程--独创编程方式,可能会流行

多年来我们程序员已经习惯了编程模式--坐着编程 一来到编程办公室,我们马上坐下,打开空调,松软的旋转座椅,坐下来就可以编程.于是人们只知道世界上只有这种编程模式--坐着编程. 这个模式不是不好,可是如果坚持只用这个编程模式,会带来严重问题,坐久了屁股痛,最后没办法坐了.于是只能躺着编程. 坐着编程,身体缺少运动,每况愈下,身体不堪负重,垮了.生成各种疾病,最后竟然有的程序员英年死去,没办法编程了! 我编程十几年,曾经也是运动健将,但是因为坐着编程,身体也不行了,坐下没多久屁股就痛了.现在是左右为

CUDA C编程入门-编程模型

这章节介绍CUDA编程模型的主要的概念. 2.1.kernels(核函数) CUDA C扩展了C语言,允许程序员定义C函数,称为kernels(核函数).并行地在N个CUDA线程中执行N次. 使用__global__说明符声明一个核函数,调用使用<<<...>>>,并且指定执行的CUDA线程数目.执行的每个线程都有一个独一的ID,在核函数中可以通过变量threadIdx获取. 例子,两个向量的加,A加B,并把结果存入C,A.B和C的长度为N. __global__ vo