C/C++ TCP客户端服务器简单示例

Posted 福州-司马懿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C/C++ TCP客户端服务器简单示例相关的知识,希望对你有一定的参考价值。

使用VS2010新建2个项目,一个叫 “tcpserver” ,另一个叫 “tcpclient”。

右击 "项目" --> "属性" --> "配置属性" --> "链接器" --> "输入" --> "附加依赖项" ,在右侧下拉框中点击 “编辑” 按钮,添加 “WS2_32.lib”,单击确定。

1、项目tcpserver

// tcpserver.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <WinSock2.h>
#include <stdio.h>

#define SERVERPORT 6222 //服务器端口

int _tmain(int argc, _TCHAR* argv[])
{
	//用来保存WinSock库的版本号
	WORD wVersionRequested;
	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;
	//将主机字节顺序转换为TCP/IP网络字节顺序
	addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	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);
	bool isStart = true;
	while(isStart) {
		//等待客户端请求到来
		SOCKET sockConn = accept(sockServer, (SOCKADDR*)&addrClient, &len);
		if(sockConn == INVALID_SOCKET) {
			printf("accept() called failed! 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、项目tcpclient

// tcpclient.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <WinSock2.h>
#include <stdio.h>

#define SERVER_PORT 6222 //服务器端口号
#define BUFF_SIZE 1024
#pragma comment(lib, "WS2_32.lib")

int _tmain(int argc, _TCHAR* 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\\n", WSAGetLastError());
		return -1;
	} else {
		printf("socket() called successful!\\n");
	}
	//需要连接的服务端套接字结构信息
	SOCKADDR_IN addrServer;
	//设定服务器IP
	addrServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	addrServer.sin_family = AF_INET;
	//设定服务器的端口号(使用网络字节序) 
	addrServer.sin_port = htons(SERVER_PORT);
	//向服务器发出连接请求
	err = connect(sockClient, (SOCKADDR*)&addrServer, sizeof(SOCKADDR));
	if(err == SOCKET_ERROR) {
		printf("connect() called failed! The error code is %d\\n", WSAGetLastError());
	} else {
		printf("connect() called successful\\n");
	}
	//接收数据
	char recvBuf[BUFF_SIZE] = {0};
	recv(sockClient, recvBuf, 100, 0);
	printf("receive data from server side is: %s\\n", recvBuf);
	//发送数据
	char buf[] = "This is a client side!\\n";
	send(sockClient, buf, strlen(buf)+1, 0);
	//关闭套接字
	closesocket(sockClient);
	//终止套接字库的使用
	WSACleanup();
	system("pause");
	return 0;
}
3、运行实际截图

(1)连接成功


(2)客户端连接失败