TCP_IP

这是一个关于如何使用TCP协议实现客户端与服务端通信的示例代码。客户端首先连接到服务端,然后通过循环发送和接收字符串,直到接收到'quit'指令。服务端则监听特定端口,接收客户端请求,接收数据并回显,同样在接收到'quit'时终止通信。
摘要由CSDN通过智能技术生成

这个就是记录一次模拟客户端和服务端利用TCP协议通信
一定要先开启服务端再开启客户端

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

#include “stdafx.h”

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

#pragma comment(lib,“WS2_32.lib”)
#define BUF_SIZE 4096 // 缓冲区大小

int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsd; // 用于初始化Windows Socket
SOCKET sHost; // 与服务器进行通信的套接字
SOCKADDR_IN servAddr; // 服务器地址
char buf[BUF_SIZE]; // 用于接受数据缓冲区
int retVal; // 调用各种Socket函数的返回值
// 初始化Windows Socket
if(WSAStartup(MAKEWORD(2,2),&wsd) != 0)
{
printf(“WSAStartup failed !\n”);
return 1;
}
// 创建套接字
sHost = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(INVALID_SOCKET == sHost)
{
printf(“socket failed !\n”);
WSACleanup();
return -1;
}
// 设置服务器地址
servAddr.sin_family = AF_INET;
servAddr.sin_addr.S_un.S_addr = inet_addr(“127.0.0.1”); // 用户需要根据实际情况修改
servAddr.sin_port = htons(9990); // 在实际应用中,建议将服务器的IP地址和端口号保存在配置文件中
int sServerAddlen = sizeof(servAddr); // 计算地址的长度
// 连接服务器
retVal = connect(sHost,(LPSOCKADDR)&servAddr,sizeof(servAddr));
// 循环等待
while (INVALID_SOCKET == retVal)
{
if(INVALID_SOCKET == retVal)
{
int err = WSAGetLastError();
if(err == WSAEWOULDBLOCK) // 无法立即完成非阻塞套接字上的操作
{
//Sleep(500);
continue;
}
else
{
printf(“accept failed !\n”);
closesocket(sHost);
WSACleanup();
return -1;
}
}
}
// 循环向服务器发送字符串,并显示反馈信息。
// 发送quit将使服务器程序退出,同时客户端程序自身也将退出
while(true)
{
// 向服务器发送数据
printf("Please input a string to send: ");
// 接收输入的数据
//以下是C++方式获得字符串

	std::string str;
	std::getline(std::cin, str);
	// 将用户输入的数据复制到buf中
	ZeroMemory(buf,BUF_SIZE);   
	strcpy(buf,str.c_str());   
    
	/*//以下是C语言方式获得字符串
	char buf2[50];
	ZeroMemory(buf2, 50);
	//scanf("%s",buf2);
	gets_s(buf2);
	//使用C语言方式获得字符串时需要特别注意,在send和recv函数中的缓冲区长度字段应设置为与发送字符串相同的大小,否则出现乱码*/

	// 向服务器发送数据
	//retVal = send(sHost,buf, 50,0);   //C语言方式获得字符串,指定缓冲区长度大小
	retVal = send(sHost, buf, strlen(buf), 0);  //C++方式获取字符串按系统设定缓冲区大小即可,可以与发送字符串长度不相同
	if(SOCKET_ERROR == retVal)   
	{   
		printf("send failed !\n");   
		closesocket(sHost);   
		WSACleanup();   
		return -1;   
	}   	  
	
	// 接收服务器回传的数据   
	
	//retVal = recv(sHost,buf,50,0);   
	retVal = recv(sHost, buf, sizeof(buf)+1, 0);
	printf("Recv From Server: %s\n",buf);   
	// 如果收到quit,则退出
	if(strcmp(buf, "quit") == 0)
	{
		printf("quit!\n");
		break;
	}
    
}
// 释放资源   
closesocket(sHost);   
WSACleanup();   
// 暂停,按任意键继续
system("pause");
return 0;  

}

//TCPServer.cpp 程序服务端
#include “stdafx.h”
#include <WinSock2.h>
#include
#include <tchar.h>
#pragma comment(lib,“WS2_32.lib”)

#define BUF_SIZE 4096

int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsd; //WSADATA变量,用于初始化Windows Sockets
SOCKET sServer; //服务器Socket,用于监听客户端请求
SOCKET sClient; //客户端Socket,用于实现与客户端的通信
int retVal; //调用各种Socket函数的返回值
char buf[BUF_SIZE]; //用于接收客户端数据的缓冲区

//初始化Socket动态库
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{
	printf("WSAStartup failed !\n");
	return -1;
}

//创建用于监听的Socket
sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == sServer)
{
	printf("socket failed !\n");
	WSACleanup();//销毁资源
	return -1;
}

//设置服务器Socket地址
SOCKADDR_IN addrServ;                            //服务器的地址信息
addrServ.sin_family = AF_INET;                  //ipv4协议
addrServ.sin_port = htons(9990);                //监听端口为9990
addrServ.sin_addr.S_un.S_addr = htonl(INADDR_ANY); //绑定的是主机任一可用的ip地址
//addrServ.sin_addr.S_un.S_addr = inet_addr("ip地址");

//绑定Sockets Server到本地地址
retVal = bind(sServer, (const struct sockaddr*)&addrServ, sizeof(SOCKADDR_IN));
if (SOCKET_ERROR == retVal)//retVal !=0
{
	printf("bind failed !\n");
	closesocket(sServer);
	WSACleanup();
	return -1;
}

//在Sockets Server上监听
retVal = listen(sServer, 1);
if (SOCKET_ERROR == retVal)
{
	printf("listen failed !\n");
	closesocket(sServer);
	WSACleanup();
	return -1;
}

//接收来自客户端的请求
printf("TCP Server start...\n");
sockaddr_in addrClient;                            //客户端地址
int addrClientlen = sizeof(addrClient);
sClient = accept(sServer, (sockaddr FAR*) & addrClient, &addrClientlen);
if (INVALID_SOCKET == sClient)
{
	printf("accept failed !\n");
	closesocket(sServer);
	WSACleanup();
	return -1;
}

//循环接收客户端的数据,直接客户端发送给quit命令后退出
while (true)
{
	ZeroMemory(buf, BUF_SIZE);                    //清空接收数据的缓冲区
	retVal = recv(sClient, buf, BUFSIZ, 0);
	if (SOCKET_ERROR == retVal)
	{
		printf("recv failed !\n");
		closesocket(sServer);
		closesocket(sClient);
		WSACleanup();
		return -1;
	}
	//获取当前系统时间
	SYSTEMTIME st;
	GetLocalTime(&st);
	char sDateTime[30];
	sprintf(sDateTime, "%4d-%2d-%2d %2d:%2d:%2d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
	printf("%s,Recv From Client [%s:%d] :%s\n", sDateTime,inet_ntoa(addrClient.sin_addr),addrClient.sin_port,buf);
	//如果客户端发送quit字符串,则服务器退出
	if (strcmp(buf, "quit") == 0)
	{
		retVal = send(sClient, "quit", strlen("quit"), 0);
		break;
	}
	//否则向客户端发送回显字符串
	else
	{
		char msg[BUF_SIZE];
		sprintf(msg, "Message received - %s", buf);     //向客户端发送回显字符串
		retVal = send(sClient, msg, strlen(msg), 0);
		if (SOCKET_ERROR == retVal)
		{
			printf("send failed !\n");
			closesocket(sServer);
			closesocket(sClient);
			WSACleanup();
			return -1;
		}
	}
}
//释放Socket
closesocket(sServer);
closesocket(sClient);
WSACleanup();

//暂停,按任意键退出
system("pause");
return 0;

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值