zoukankan      html  css  js  c++  java
  • 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 6000 //服务端口号
    #pragma comment(lib,"WS2_32.lib")
      
    int main(int argc, char *argv[])  
    {  
        //加载套接字库  
        WORD wVersionRequested;//用于保存WinSock库的版本号  
        WSADATA wsaData;  
        int err;  
          
        printf("This is a Server side application!
    ");  
      
        wVersionRequested = MAKEWORD(2,2);  
      
        err = WSAStartup( wVersionRequested, &wsaData);  
        if (err != 0)  
        {  
            printf("WSAStartup() called failed!
    ");  
            return -1;  
        }  
        else  
        {  
            printf("WSAStartup() called successful!
    ");  
        }  
      
        if (LOBYTE(wsaData.wVersion) != 2 ||  
              HIBYTE(wsaData.wVersion) != 2)  
        {  
            //若不是所请求的版本号2.2,则终止WinSock库的使用  
            WSACleanup();  
            return -1;  
        }  
      
        //创建用于监听的套接字  
        SOCKET sockServer = socket(AF_INET, SOCK_STREAM, 0);  
        if(sockServer == INVALID_SOCKET)  
        {  
            printf("socket() called failed! ,error code is: %d", WSAGetLastError());  
            return -1;  
        }  
        else  
        {  
            printf("socket() called successful!
    ");  
        }  
          
        //填充服务器端套接字结构  
        SOCKADDR_IN addrServer;  
        addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//将主机字节顺序转换成TCP/IP网络字节顺序  
        addrServer.sin_family = AF_INET;  
        addrServer.sin_port = htons(SERVERPORT);  
      
        //将套接字绑定到一个本地地址和端口上  
        err = bind(sockServer, (SOCKADDR*)&addrServer, sizeof(SOCKADDR));  
        if (err == SOCKET_ERROR)  
        {  
            printf("bind() called failed! The error code is: %d
    ", WSAGetLastError());  
            return -1;  
        }  
        else  
        {  
            printf("bind() called successful
    ");  
        }  
        //将套接字设置为监听模式,准备接收客户请求  
        err = listen(sockServer, 5);  
        if (err == SOCKET_ERROR)  
        {  
            printf("listen() called failed! The error code is: %d
    ", WSAGetLastError());  
            return -1;  
        }  
        else  
        {  
            printf("listen() called successful!
    ");  
        }  
      
        SOCKADDR_IN addrClient; //保存发送请求连接的客户端的套接字信息  
        int len = sizeof(SOCKADDR);  
          
        while(1)  
        {  
            //等待客户请求到来  
            SOCKET sockConn = accept(sockServer, (SOCKADDR*)&addrClient, &len);  
            if (sockConn == INVALID_SOCKET)  
            {  
                printf("accept() called falied! The error code is: %d
    ", WSAGetLastError());  
            }  
            else  
            {  
                printf("The Server receive a new client connection!
    ");  
            }  
      
            char sendBuf[100];  
            sprintf_s(sendBuf, 100, "Welcome %s",inet_ntoa(addrClient.sin_addr));  
      
            //发送数据  
            send(sockConn, sendBuf, strlen(sendBuf)+1 , 0);  
            char recvBuf[100];  
            //接收数据  
            recv(sockConn, recvBuf, 100, 0);  
            //打印接收到的数据  
            printf("receive data from client side [%s,%d] is: %s
    ", inet_ntoa(addrClient.sin_addr), addrClient.sin_port,  
                                  recvBuf);  
            closesocket(sockConn);  //关闭连接套接字  
        }  
      
        return 0;  
    }  

    2、客户端代码

    #include <WinSock2.h>  
    #include <stdio.h>  
      
    #define SERVERPORT 6000 //服务端口号  
      
    #pragma comment(lib, "WS2_32.lib")
      
    int main(int argc, char *argv[])  
    {  
        //加载套接字库  
        WORD wVersionRequested;  
        WSAData wsaData;  
        int err;  
      
        printf("This is a Client side application!
    ");  
      
        wVersionRequested = MAKEWORD( 2, 2 );  
      
        err = WSAStartup(wVersionRequested, &wsaData);  
        if (err != 0 )  
        {  
            /* Tell the user that we could not find a usable */  
            /* WinSock DLL.                                  */  
            printf("WSAStartup() called failed!
    ");  
            return -1;  
        }  
        else  
        {  
            printf("WSAStartup() called successful!
    ");  
        }  
      
        if ( LOBYTE( wsaData.wVersion ) != 2 ||  
            HIBYTE( wsaData.wVersion ) != 2 ) {  
                /* Tell the user that we could not find a usable */  
                /* WinSock DLL.                                  */  
                WSACleanup( );  
                return -1;   
        }  
      
        /* The WinSock DLL is acceptable. Proceed. */  
          
        //创建套接字  
        SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);  
        if(sockClient == INVALID_SOCKET)  
        {  
            printf("socket() called failed! ,error code is: %d", WSAGetLastError());  
            return -1;  
        }  
        else  
        {  
            printf("socket() called successful!
    ");  
        }  
          
        //需要连接的服务端套接字结构信息  
        SOCKADDR_IN addrServer;  
        addrServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//设定服务器的IP地址  
        addrServer.sin_family = AF_INET;  
        addrServer.sin_port = htons(SERVERPORT);//设定服务器的端口号(使用网络字节序)  
            
        //向服务器发出连接请求  
        err = connect(sockClient, (SOCKADDR*)&addrServer, sizeof(SOCKADDR));  
        if (err == SOCKET_ERROR)  
        {  
            printf("connect() called failed! The error code is: %d
    ", WSAGetLastError());  
            return -1;  
        }  
        else  
        {  
            printf("connect() called successful
    ");  
        }  
      
        //接收数据  
        char recvBuf[100]={0};  
        recv(sockClient, recvBuf, 100, 0);  
        printf("receive data from server side is: %s
    ", recvBuf);  
                                             
        //发送数据  
        send(sockClient, "This is a client side!
    ", strlen("This is a client side!
    ")+1, 0);  
      
        //关闭套接字  
        closesocket(sockClient);  
          
        //终止套接字库的使用  
        WSACleanup();  
      
        return 0;  
    }  

    另外,需要注意的是需要在服务器和客户端都需要链接WinSock静态链接库Ws2_32.lib,有两种添加方法

    方法一:在工程配置属性中添加

    假如创建一个名为TCPClient的Win32控制台应用程序

    在VC2008中添加静态链接库WS2_32.lib的方法如下:

    (1)切换到TCPServer的【Solution Explorer】,选择菜单【Project】->【TCPClient Properties】

    (2)在TCPClient Properties Pages对话框中,依次选择【Configuration Properties】->【Linker】->【Input】,在右侧的【Addtional Dependencies】中添加Ws2_32.lib库。

    如下如所示:

    服务器TCPServer也需要链接Ws2_32.lib库,方法和客户端TCPClient一样。

    程序结果运行如下:

    先启动服务器端程序TCPServer,结果如下:

    再启动客户端TCPClient,客户端结果如下:

    服务器端TCPServer结果如下:

    方法二:在代码中添加

    #pragma comment(lib, "WS2_32.lib");

    参考资料:

    1、《VC++深入详解》 第14章网络编程 ,孙鑫主编

    2、MSDN帮助文档

     原文链接:VC++ TCP网络控制台程序

  • 相关阅读:
    利用python 掌握机器学习的过程
    SendMessage用法
    python函数形参中的*args和**kwargs
    python 用win32修改注册表,修改打开IE浏览器的配置
    python .py .pyc .pyw .pyo .pyd区别
    代码性能提升10倍(ForkJoin)
    雪花算法生成id
    配置虚拟机
    kafka多线程消费
    Redis存储对象序列化和反序列化
  • 原文地址:https://www.cnblogs.com/rainbow70626/p/8059106.html
Copyright © 2011-2022 走看看