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!\n");  

    wVersionRequested = MAKEWORD(2,2);  

    err = WSAStartup( wVersionRequested, &wsaData);
    if (err != 0)
    {
        printf("WSAStartup() called failed!\n");
        return -1;
    }
    else
    {
        printf("WSAStartup() called successful!\n");
    }  

    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!\n");
    }  

    //填充服务器端套接字结构
    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\n", WSAGetLastError());
        return -1;
    }
    else
    {
        printf("bind() called successful\n");
    }
    //将套接字设置为监听模式,准备接收客户请求
    err = listen(sockServer, 5);
    if (err == SOCKET_ERROR)
    {
        printf("listen() called failed! The error code is: %d\n", WSAGetLastError());
        return -1;
    }
    else
    {
        printf("listen() called successful!\n");
    }  

    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\n", WSAGetLastError());
        }
        else
        {
            printf("The Server receive a new client connection!\n");
        }  

        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\n", 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!\n");  

    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!\n");
        return -1;
    }
    else
    {
        printf("WSAStartup() called successful!\n");
    }  

    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!\n");
    }  

    //需要连接的服务端套接字结构信息
    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\n", WSAGetLastError());
        return -1;
    }
    else
    {
        printf("connect() called successful\n");
    }  

    //接收数据
    char recvBuf[100]={0};
    recv(sockClient, recvBuf, 100, 0);
    printf("receive data from server side is: %s\n", recvBuf);  

    //发送数据
    send(sockClient, "This is a client side!\n", strlen("This is a client side!\n")+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网络控制台程序

时间: 2024-08-07 15:49:00

VC++ TCP网络控制台程序的相关文章

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

【UNIX网络编程(三)】TCP客户/服务器程序示例

上一节给出了TCP网络编程的函数,这一节使用那些基本函数编写一个完成的TCP客户/服务器程序示例. 该例子执行的步骤如下: 1.客户从标准输入读入一行文本,并写给服务器. 2.服务器从网络输入读入这行文本,并回射给客户. 3.客户从网络输入读入这行回射文本,并显示在标准输出上. 用图描述如下: 编写TCP回射服务器程序如下: #include <stdio.h> #include <errno.h> #include <stdlib.h> #include <st

第5章-unix网络编程 TCP/服务端程序示例

这一章主要是完成一个完整的tcp客户/服务器程序.通过一很简单的例子.弄清客户和服务器如何启动,如何终止,发生了某些错误会发生什么.这些事很重要的 客户端代码 #include "unp.h" //static void str_cli1(FILE*fp,int sockfd); int main(int argc,char *argv[]) { int sockfd; struct sockaddr_in servaddr; sockfd=Socket(AF_INET,SOCK_ST

UNIX网络编程笔记(4)—TCP客户/服务器程序示例

TCP客户/服务器程序示例 这一章信息量开始大起来了,粗略来看它实现了简单的TCP客户/服务器程序,里面也有一些费解的细节. 1.概述 完整的TCP客户/服务器程序示例.这个简单的例子将执行如下步骤的一个回射服务器(这里的回射服务器就是服务简单的把客户端发送的消息返回给客户): 1)客户从标准输入读入一行文本,并写给服务器 2)服务器从网络输入读入这行文本,并回射给客户 3)客户从网络输入读入这行回射文本,并显示在标准输出上 这样实际上就构成了一个全双工的TCP连接. 本章就围绕了这个简单的TC

powershell 查看程序的tcp网络连接

在运维工作中,经常查看某个业务的网络连接状况,在这里借用netstat来实现查找连接,用hash特性避免重复. [email protected]{} while(1){ ps|?{$_.path -match 'E:\\games\\梦幻XX}|%{ $id=$_.id netstat -ano | ForEach-Object { $i = $_ | Select-Object -Property Protocol , Source , Destination , Mode ,pid $nu

UNIX网络编程入门——TCP客户/服务器程序详解

前言 最近刚开始看APUE和UNP来学习socket套接字编程,因为网络这方面我还没接触过,要等到下学期才上计算机网络这门课,所以我就找了本教材啃了一两天,也算是入了个门. 至于APUE和UNP这两本书,书是好书,网上也说这书是给进入unix网络编程领域初学者的圣经,这个不可置否,但这个初学者,我认为指的是接受过完整计算机本科教育的研究生初学者,需要具有完整计算机系统,体系结构,网络基础知识.基础没打好就上来啃书反而会适得其反,不过对于我来说也没什么关系,因为基础课也都上得差不多了,而且如果书读

C、C++控制台程序、Windows API程序、MFC程序理解与比较

在编程语言中,函数是一个很重要的概念,其身影无处不在.在面向过程的编程方式中,函数更是程序的基本构建模块,在面向对象的编程方式中,函数演变为类或对象的成员(当然也可以使用与类无关的函数).函数由函数头和函数体组成.函数头包括域属性(如external.static或类域).返回值类型.函数名.及参数.域属性包括其在多文件编程中的可见范围,是否是属于某一个类的成员?返回值类型是指函数返回的值的具体数据类型(可以理解为函数输出的一部分).函数名是函数保存在内存代码区的首地址,用于函数的调用及函数指针

boost asio异步读写网络聊天程序客户端 实例详解

// // chat_client.cpp // ~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://ww

Java - TCP网络编程

Java - TCP网络编程 Server 逻辑思路: 创建ServerSocket(port),然后服务器的socket就启动了 循环中调用accept(),此方法会堵塞程序,直到发现用户请求,返回用户的socket 利用多线程对用户socket进行IO操作 注意:对Scoket/File进行创建.关闭,都需要放try catch中,检测 IOException,所以将网络IO部分整体放入try catch中即可. 1. 字符串操作 输出:PrintWriter out=new PrintWr