ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

TCPIP实验1、2(面向连接的Socket编程)

2020-12-06 15:03:11  阅读:212  来源: 互联网

标签:addr Socket buf 编程 SOCKET printf retVal sin TCPIP


实验目的:

学习SOCKET编程基础,掌握Winsock主要库函数

实验效果:

  1. 客户和服务器之间都可以在键盘上输入语句并且发送给对方,并且都可以接收对方发送来的语句,并且在显示器上显示。
  2. 显示服务器端的点分十进制IP地址,long 型IP地址,short型IP地址和Char型IP地址。
  3. 服务器显示客户端点分十进制IP地址,客户端显示服务器点分十进制IP地址

特别说明

我的实验设备:Microsoft Visual Studio 2013(不同的工具某些函数会略有不同,但是英语只要四级过了,主要看报错提示都能解决,其中6.0版本头文件不能有#include “stdafx.h”)

各位梭友自行更改ip地址哟,以后就霸道得默认你们都知道。(方法是win+r输入ipconfig/all)
在这里插入图片描述
第一部分运行结果显示:
在这里插入图片描述

// 大作业客户端.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <Winsock2.H>    
#include <string>
#include <iostream>
#pragma comment(lib,"WS2_32.lib")   
#define BUF_SIZE    65535          // 缓冲区大小  

int main(int argc, CHAR* argv[])
{
	WSADATA     wsd;					// 用于初始化Windows Socket   
	SOCKET      sHost;					// 与服务器进行通信的套接字   
	SOCKADDR_IN servAddr;			// 服务器地址   
	//SOCKET  sServer;					// 服务器套接字,用于监听客户端请求
	//SOCKET  sClient;					// 客户端套接字,用于实现与客户端的通信 
	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("192.168.43.62");		// 用户需要根据实际情况修改
	servAddr.sin_port = htons(9990);													// 在实际应用中,建议将服务器的IP地址和端口号保存在配置文件中
	int sServerAddlen = sizeof(servAddr);												// 计算地址的长度       
	// 连接服务器   
	retVal = connect(sHost, (LPSOCKADDR)&servAddr, sizeof(servAddr));
	if (retVal == SOCKET_ERROR){
		printf("connect failed!\n");
		closesocket(sHost);
		WSACleanup();
		return -1;
	}

	// 循环向服务器发送字符串,并显示反馈信息。
	// 发送quit将使服务器程序退出,同时客户端程序自身也将退出
	int count = 1;
	while (count<10)
	{
		// 向服务器发送数据   
		printf("Please input a string to send: ");
		// 接收输入的数据
		std::string str;
		std::getline(std::cin, str);
		getchar();
		// 将用户输入的数据复制到buf中
		ZeroMemory(buf, BUF_SIZE);
		strcpy_s(buf, str.c_str());
		// 向服务器发送数据


		retVal = send(sHost, buf, strlen(buf), 0);
		if (SOCKET_ERROR == retVal)
		{
			printf("send failed !\n");
			closesocket(sHost);
			WSACleanup();
			return -1;
		}
		ZeroMemory(buf, BUF_SIZE);// 清空接收数据的缓冲区
		// 接收服务器回传的数据   
		retVal = recv(sHost, buf, BUFSIZ, 0);
		printf("Message aply : %s\n", buf);
		printf("---------第 %d 次对话结束-----------\n", count);
		count++;
	}
	// 释放资源   
	closesocket(sHost);
	WSACleanup();
	// 暂停,按任意键继续
	system("pause");
	return 0;
}

// 大作业服务器端.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <WINSOCK2.H>  
#include <string> 
#include <iostream>  
#pragma comment(lib,"WS2_32.lib")   
#define BUF_SIZE    65535      // 缓冲区大小

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

	// 初始化套接字动态库   
	if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0){
		printf("WSAStartup failed!\n");
		return -1;
	}
	// 创建用于监听的套接字   
	sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (INVALID_SOCKET == sServer){
		printf("socket failed!\n");
		WSACleanup();
		return -1;
	}
	// 设置服务器套接字地址   
	SOCKADDR_IN addrServ;
	addrServ.sin_family = AF_INET;
	addrServ.sin_port = htons(9990);		// 监听端口为9990
	//addrServ.sin_addr.S_un.S_addr = htonl(INADDR_ANY);  
	addrServ.sin_addr.S_un.S_addr = inet_addr("192.168.43.62");
	// 绑定套接字sServer到本地地址,端口9990  
	retVal = bind(sServer, (const struct sockaddr*)&addrServ, sizeof(SOCKADDR_IN));
	if (retVal == SOCKET_ERROR){
		printf("bind failed!\n");
		closesocket(sServer);
		WSACleanup();
		return -1;
	}
	// 监听套接字   
	retVal = listen(sServer, 1);
	if (retVal == SOCKET_ERROR){
		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 (sClient == INVALID_SOCKET){
		printf("accept failed!\n");
		closesocket(sServer);
		WSACleanup();
		return -1;
	}
	// 循环接收客户端的数据,直接客户端发送了10次数据后退出。  
	int count = 1;
	while (count<10)
	{
		ZeroMemory(buf, BUF_SIZE);	// 清空接收数据的缓冲区
		//接收数据
		retVal = recv(sClient, buf, BUFSIZ, 0);
		if (retVal == SOCKET_ERROR){
			printf("recv failed!\n");
			closesocket(sServer);
			closesocket(sClient);
			WSACleanup();
			return -1;
		}
		// 获取当前系统时间
		SYSTEMTIME st;
		GetLocalTime(&st);
		char sDateTime[30];
		sprintf_s(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);
		//向客户端发送回复消息
		printf("Please input a string to send to client: ");
		// 接收输入的数据
		std::string str;
		std::getline(std::cin, str);
		getchar();
		// 将用户输入的数据复制到buf中
		ZeroMemory(buf, BUF_SIZE);
		strcpy_s(buf, str.c_str());
		// 向服务器发送数据

		char    msg[BUF_SIZE];
		sprintf_s(msg, " %s", buf);
		retVal = send(sClient, msg, strlen(msg), 0);
		if (SOCKET_ERROR == retVal)
		{
			printf("send failed !\n");
			closesocket(sServer);
			closesocket(sClient);
			WSACleanup();
			return -1;
		}
		printf("---------第 %d 次对话结束-----------\n", count);
		count++;
	}
	//服务器退出 释放套接字   
	closesocket(sServer);
	closesocket(sClient);
	WSACleanup();
	// 暂停,按任意键退出
	system("pause");
	return 0;
}

第二和三部分运行效果(只需要理解代码中的“增加部分就行”):
在这里插入图片描述

// 大作业服务器端.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <WINSOCK2.H>  
#include <string> 
#include <iostream>  
#pragma comment(lib,"WS2_32.lib")   
#define BUF_SIZE    65535      // 缓冲区大小

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

	// 初始化套接字动态库   
	if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0){
		printf("WSAStartup failed!\n");
		return -1;
	}
	// 创建用于监听的套接字   
	sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (INVALID_SOCKET == sServer){
		printf("socket failed!\n");
		WSACleanup();
		return -1;
	}
	// 设置服务器套接字地址   
	SOCKADDR_IN addrServ;
	addrServ.sin_family = AF_INET;
	addrServ.sin_port = htons(9990);		// 监听端口为9990
	//addrServ.sin_addr.S_un.S_addr = htonl(INADDR_ANY);  
	addrServ.sin_addr.S_un.S_addr = inet_addr("192.168.43.62");
	// 绑定套接字sServer到本地地址,端口9990  
	retVal = bind(sServer, (const struct sockaddr*)&addrServ, sizeof(SOCKADDR_IN));
	if (retVal == SOCKET_ERROR){
		printf("bind failed!\n");
		closesocket(sServer);
		WSACleanup();
		return -1;
	}
	//———————————————————————————增加内容———————————
	printf("显示服务器端的点分十进制IP地址,long 型IP地址,short型IP地址和Char型IP地址:\n");
	printf("服务器IP地址:%s \r\n", inet_ntoa(addrServ.sin_addr));
	printf_s("服务器(long型)IP地址:%ld \r\n", addrServ.sin_addr.S_un.S_addr);
	printf_s("服务器(short型)IP地址:%d %d\r\n", addrServ.sin_addr.S_un.S_un_w.s_w1, addrServ.sin_addr.S_un.S_un_w.s_w2);
	printf_s("服务器(char型)IP地址:%d %d %d %d\r\n", addrServ.sin_addr.S_un.S_un_b.s_b1, addrServ.sin_addr.S_un.S_un_b.s_b2, addrServ.sin_addr.S_un.S_un_b.s_b3, addrServ.sin_addr.S_un.S_un_b.s_b4);
	//——————————————————————————————————————————
	// 监听套接字   
	retVal = listen(sServer, 1);
	if (retVal == SOCKET_ERROR){
		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 (sClient == INVALID_SOCKET){
		printf("accept failed!\n");
		closesocket(sServer);
		WSACleanup();
		return -1;
	}
	// 循环接收客户端的数据,直接客户端发送了10次数据后退出。  
	int count = 1;
	while (count<2)
	{
		ZeroMemory(buf, BUF_SIZE);	// 清空接收数据的缓冲区
		//接收数据
		retVal = recv(sClient, buf, BUFSIZ, 0);
		//———————————————————————增加内容—————
		if (retVal > 0){
			printf("\nrecv函数调用成功,在服务器端显示客户端的IP地址:%s \r\n", inet_ntoa(addrClient.sin_addr));

		}
		if (retVal == 0){
			printf("连接已经关闭");
		}
		//————————————————————————————————
		if (retVal == SOCKET_ERROR){
			printf("recv failed!\n");
			closesocket(sServer);
			closesocket(sClient);
			WSACleanup();
			return -1;
		}
		// 获取当前系统时间
		SYSTEMTIME st;
		GetLocalTime(&st);
		char sDateTime[30];
		sprintf_s(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);
		//向客户端发送回复消息
		printf("Please input a string to send to client: ");
		// 接收输入的数据
		std::string str;
		std::getline(std::cin, str);
		getchar();
		// 将用户输入的数据复制到buf中
		ZeroMemory(buf, BUF_SIZE);
		strcpy_s(buf, str.c_str());
		// 向服务器发送数据

		char    msg[BUF_SIZE];
		sprintf_s(msg, " %s", buf);
		retVal = send(sClient, msg, strlen(msg), 0);
		if (SOCKET_ERROR == retVal)
		{
			printf("send failed !\n");
			closesocket(sServer);
			closesocket(sClient);
			WSACleanup();
			return -1;
		}
		printf("---------第 %d 次对话结束-----------\n", count);
		count++;
	}
	//服务器退出 释放套接字   
	closesocket(sServer);
	closesocket(sClient);
	WSACleanup();
	// 暂停,按任意键退出
	system("pause");
	return 0;
}



// 大作业客户端.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <Winsock2.H>    
#include <string>
#include <iostream>
#pragma comment(lib,"WS2_32.lib")   
#define BUF_SIZE    65535          // 缓冲区大小  

int main(int argc, CHAR* argv[])
{
	WSADATA     wsd;					// 用于初始化Windows Socket   
	SOCKET      sHost;					// 与服务器进行通信的套接字   
	SOCKADDR_IN servAddr;			// 服务器地址   
	//SOCKET  sServer;					// 服务器套接字,用于监听客户端请求
	//SOCKET  sClient;					// 客户端套接字,用于实现与客户端的通信 
	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("192.168.43.62");	// 用户需要根据实际情况修改
	servAddr.sin_port = htons(9990);// 在实际应用中,建议将服务器的IP地址和端口号保存在配置文件中
	int sServerAddlen = sizeof(servAddr);// 计算地址的长度 


	// 连接服务器   
	retVal = connect(sHost, (LPSOCKADDR)&servAddr, sizeof(servAddr));
	if (retVal == SOCKET_ERROR){
		printf("connect failed!\n");
		closesocket(sHost);
		WSACleanup();
		return -1;
	}

	// 循环向服务器发送字符串,并显示反馈信息。
	// 发送quit将使服务器程序退出,同时客户端程序自身也将退出
	int count = 1;
	while (count<2)
	{
		// 向服务器发送数据   
		printf("Please input a string to send: ");
		// 接收输入的数据
		std::string str;
		std::getline(std::cin, str);
		getchar();
		// 将用户输入的数据复制到buf中
		ZeroMemory(buf, BUF_SIZE);
		strcpy_s(buf, str.c_str());
		// 向服务器发送数据


		retVal = send(sHost, buf, strlen(buf), 0);
		if (SOCKET_ERROR == retVal)
		{
			printf("send failed !\n");
			closesocket(sHost);
			WSACleanup();
			return -1;
		}
		ZeroMemory(buf, BUF_SIZE);// 清空接收数据的缓冲区
		// 接收服务器回传的数据   
		retVal = recv(sHost, buf, BUFSIZ, 0);
		//————————————————————————————————增加内容————————
		if (retVal > 0){
			printf("\nrecv函数调用成功,在客户端显示服务器的IP地址:%s \r\n", inet_ntoa(servAddr.sin_addr));

		}
		if (retVal == 0){
			printf("连接已经关闭");
		}
		//————————————————————————————————————————
		printf("Message aply : %s\n", buf);
		printf("---------第 %d 次对话结束-----------\n", count);
		count++;
	}
	// 释放资源   
	closesocket(sHost);
	WSACleanup();
	// 暂停,按任意键继续
	system("pause");
	return 0;
}

标签:addr,Socket,buf,编程,SOCKET,printf,retVal,sin,TCPIP
来源: https://blog.csdn.net/XMY_UPUPUP/article/details/110732445

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有