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(,); err = WSAStartup( wVersionRequested, &wsaData);
if (err != )
{
printf("WSAStartup() called failed!\n");
return -;
}
else
{
printf("WSAStartup() called successful!\n");
} if (LOBYTE(wsaData.wVersion) != ||
HIBYTE(wsaData.wVersion) != )
{
//若不是所请求的版本号2.2,则终止WinSock库的使用
WSACleanup();
return -;
} //创建用于监听的套接字
SOCKET sockServer = socket(AF_INET, SOCK_STREAM, );
if(sockServer == INVALID_SOCKET)
{
printf("socket() called failed! ,error code is: %d", WSAGetLastError());
return -;
}
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 -;
}
else
{
printf("bind() called successful\n");
}
//将套接字设置为监听模式,准备接收客户请求
err = listen(sockServer, );
if (err == SOCKET_ERROR)
{
printf("listen() called failed! The error code is: %d\n", WSAGetLastError());
return -;
}
else
{
printf("listen() called successful!\n");
} SOCKADDR_IN addrClient; //保存发送请求连接的客户端的套接字信息
int len = sizeof(SOCKADDR); while()
{
//等待客户请求到来
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[];
sprintf_s(sendBuf, , "Welcome %s",inet_ntoa(addrClient.sin_addr)); //发送数据
send(sockConn, sendBuf, strlen(sendBuf)+ , );
char recvBuf[];
//接收数据
recv(sockConn, recvBuf, , );
//打印接收到的数据
printf("receive data from client side [%s,%d] is: %s\n", inet_ntoa(addrClient.sin_addr), addrClient.sin_port,
recvBuf);
closesocket(sockConn); //关闭连接套接字
} return ;
}
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( , ); err = WSAStartup(wVersionRequested, &wsaData);
if (err != )
{
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
printf("WSAStartup() called failed!\n");
return -;
}
else
{
printf("WSAStartup() called successful!\n");
} if ( LOBYTE( wsaData.wVersion ) != ||
HIBYTE( wsaData.wVersion ) != ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
WSACleanup( );
return -;
} /* The WinSock DLL is acceptable. Proceed. */ //创建套接字
SOCKET sockClient = socket(AF_INET, SOCK_STREAM, );
if(sockClient == INVALID_SOCKET)
{
printf("socket() called failed! ,error code is: %d", WSAGetLastError());
return -;
}
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 -;
}
else
{
printf("connect() called successful\n");
} //接收数据
char recvBuf[]={};
recv(sockClient, recvBuf, , );
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")+, ); //关闭套接字
closesocket(sockClient); //终止套接字库的使用
WSACleanup(); return ;
}
另外,需要注意的是需要在服务器和客户端都需要链接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网络控制台程序
VC++ TCP网络控制台程序的更多相关文章
- VC++ UDP网络控制台程序
采用的是VC2008,控制台应用程序,使用UDP编写. 1.服务端代码 //UDPServer.cpp #include <WinSock2.h> #include <stdio. ...
- VC无窗口控制台程序
VC无窗口控制台程序 #pragma comment(linker,"/subsystem:\"Windows\" /entry:\"mainCRTStartu ...
- 【UNIX网络编程(三)】TCP客户/server程序演示样例
上一节给出了TCP网络编程的函数.这一节使用那些基本函数编写一个完毕的TCP客户/server程序演示样例. 该样例运行的过程例如以下: 1.客户从标准输入读入一行文本,并写给server. 2.se ...
- C#网络编程TCP通信实例程序简单设计
C#网络编程TCP通信实例程序简单设计 采用自带 TcpClient和TcpListener设计一个Tcp通信的例子 只实现了TCP通信 通信程序截图: 压力测试服务端截图: 俩个客户端链接服务端测试 ...
- UNIX网络编程 第5章 TCP客户/服务器程序示例
UNIX网络编程 第5章 TCP客户/服务器程序示例
- 大比速:remoting、WCF(http)、WCF(tcp)、WCF(RESTful)、asp.net core(RESTful) .net core 控制台程序使用依赖注入(Autofac)
大比速:remoting.WCF(http).WCF(tcp).WCF(RESTful).asp.net core(RESTful) 近来在考虑一个服务选型,dotnet提供了众多的远程服务形式.在只 ...
- 第5章-unix网络编程 TCP/服务端程序示例
这一章主要是完成一个完整的tcp客户/服务器程序.通过一很简单的例子.弄清客户和服务器如何启动,如何终止,发生了某些错误会发生什么.这些事很重要的 客户端代码 #include "unp. ...
- VC++中的C运行时库浅析(控制台程序默认使用单线程的静态链接库,而MFC中的CFile类已暗藏了多线程)
1.概论 运行时库是程序在运行时所需要的库文件,通常运行时库是以LIB或DLL形式提供的.C运行时库诞生于20世纪70年代,当时的程序世界还很单纯,应用程序都是单线程的,多任务或多线程机制在此时还属于 ...
- 《Unix 网络编程》05:TCP C/S 程序示例
TCP客户/服务器程序示例 系列文章导航:<Unix 网络编程>笔记 目标 ECHO-Application 结构如下: graph LR; A[标准输入/输出] --fgets--> ...
随机推荐
- 【SSH网上商城项目实战18】过滤器实现购物登录功能的判断
转自:https://blog.csdn.net/eson_15/article/details/51425010 上一节我们做完了购物车的基本操作,但是有个问题是:当用户点击结算时,我们应该做一个登 ...
- eclipse中编写运行c/c++
注意:此过程有点复杂 准备:1.MinGW:c/c++运行环境: 2.CDT 1.MinGW:安装程序:http://sourceforge.net/projects/mingw/?source=ty ...
- PAT 1032. Sharing
其实就是链表求交: #include <iostream> #include <cstdio> #include <cstdlib> #include <un ...
- Bzoj2395: [Balkan 2011]Timeismoney(最小乘积生成树)
问题描述 每条边两个权值 \(x,y\),求一棵 \((\sum x) \times (\sum y)\) 最小的生成树 Sol 把每一棵生成树的权值 \(\sum x\) 和 \(\sum y\) ...
- websocket协议及案例
WebSocket是一种用于在服务器与客户端之间实现高效的双向通信的机制.可以解决数据实时性要求比较高的应用,比如:在线聊天,在线教育,炒股或定位等. 一:websocket产生背景: 为了解决这种实 ...
- Angular面试题三
十六.一个 angular 应用应当如何良好地分层? 目录结构的划分 1.对于小型项目,可以按照文件类型组织,比如: css Js { controllers models services ...
- linux 查看在线服务进程
输入命令:netstat -ltunp 注意,这个-与l之间是没有空格的 要对进程进行监测和控制,首先必须要了解当前进程的情况,也就是需要查看当前进程, 而ps命令(Process Status)就 ...
- Conda常用命令整理
主要参考Anaconda官方指南Using Conda:https://conda.io/docs/using/index.html 环境:Win10 64bit with conda 4.3.14 ...
- springIOC学习笔记
目录 目的 引用 xml方式 配置 配置实例 使用 底层简单模拟 全注解方式 基础 包扫描方式 配置 使用 config方式 配置 使用 spring整合junit 引用 示例 目的 让spring统 ...
- EF中使用SqlQuery执行语句
string sql = @" SELECT B.[FId], A.[FileTypeNo], A.[FtypeName], A.[FtypeId], A.[ProcessName], A. ...