网络编程之简单网络通信

基于控制台的简单网络编程代码。

服务器代码:

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

#include "stdafx.h"
#include <WinSock2.h>
#pragma comment(lib,"Ws2_32.lib")

int _tmain(int argc, _TCHAR* argv[])
{
	WSADATA wsadata;
	//第一个参数指明程序请求的Socket版本,第二个参数指向WSADATA数据结构的指针,用来接受windows sockets实现的细节
	//当一个应用程序调用WSAStartup函数时,操作系统根据请求的Socket版本来搜索相应的Socket库,然后绑定找到的Socket库到该应用程序中
	//以后应用程序就可以调用所请求的Socket库中的其它Socket函数了。
	//一旦应用程序或者DLL进行了一次成功的WSAStartup()调用,它就可以继续进行其它所需的windows Socket API调用。当它完成了使用
	//该Windows Socket DLL的服务后,应用程序或DLL必须调用WSAClearup()以允许Windows Socket DLL释放任何该应用程序的资源。
	WSAStartup(0x0202,&wsadata);
	//第一个参数指定应用程序使用的通信协议的协议族,对于TCP/IP协议族,该参数置AF_INET
	//第二个参数指定要创建的套接字类型,流套接字类型为SOCKT_STREAM
	//第三个参数指定应用程序所使用的通信协议。此参数可以指定单个协议系列中的不同传输协议。在internet通讯域中,
	//此参数一般取值为0,系统会根据套接字的类型决定使用的传输层协议
	SOCKET ListenSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	//struct sockaddr是一个通用地址结构,这是为了统一地址结构的表示方法,统一接口函数,使不同的地址结构可以被bind(),connect()等函数
	//调用;struct sockaddr_in 中的in表示internet,就是网络地址。
	sockaddr_in ListenAddr;
	memset(&ListenAddr,0,sizeof(sockaddr_in));
	//sin_family指代协议族,在socket编程中只能是AF_INET
	ListenAddr.sin_family=AF_INET;
	//sin_port存储端口号
	ListenAddr.sin_port=htons(7070);
	//sin_addr存储IP地址,使用in_addr这个数据结构
	ListenAddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
	//bind函数用于将套接字绑定到一个已知的地址上
	//函数原型int bind(SCOKET socket,const struct sockaddr* address,socklen_t address_len);
	bind(ListenSocket,(sockaddr *)&ListenAddr,sizeof(sockaddr));
	//listen函数使主动链接套接口变为被连接套接口,使得一个进程可以接受其它进程的请求,从而成为一个服务器进程。
	//在TCP服务器编程中listen函数把进程变为一个服务器,并指定相应的套接字变为被动连接
	listen(ListenSocket,5);

	SOCKET ClientSocket=0;
	sockaddr_in ClientAddr;
	int ClientAddrLeng;
	printf("服务器启动成功!\n");

REACCEPT:
	ClientSocket=0;
	ClientAddrLeng=sizeof(sockaddr_in);
	memset(&ClientAddr,0,sizeof(sockaddr_in));
	//对于服务器编程中最重要的一步等待并接受客户的连接,那么这一步在编程中如何完成,accept函数就是完成这一步的。
	//它从内核中取出已经建立的客户连接,然后把这个已经建立的连接返回给用户程序,此时用户程序就可以与自己的客户进行点到点的通信了
	ClientSocket=accept(ListenSocket,(sockaddr *)&ClientAddr,&ClientAddrLeng);

	if(ClientSocket==INVALID_SOCKET)
	{
		printf("客户接连失败,尝试再试连接!\n");
		closesocket(ClientSocket);
		goto REACCEPT;
	}
	else
	{
		printf("[%d]客户接连成功!\n",ClientSocket);
	}
 
	char Buffer[999];
	int RecvNum=0;
	while(1)
	{	
		//不论是客户端还是服务器应用程序都用recv函数来向TCP连接的另一端接收数据
		//第一个参数指定接受另一端套接字描述符
		//第二个参数指明一个缓冲区,该缓冲区用来存放recv函数接受到的数据
		//第三个参数指明buf的长度
		//第四个参数一般置为0 
		RecvNum=recv(ClientSocket,Buffer,999,0);

		if((RecvNum==0)||(RecvNum==SOCKET_ERROR))
		{
			printf("[%d]客户断开连接或异常中断!\n",ClientSocket);
			break;
		}
		else
		{
			printf("%s\n",Buffer);
			//不论是客户端还是服务器应用程序都用send函数来向TCP连接的另一端发送数据
			//客户端程序一般用send函数向服务器发送请求,而服务器则通常用send函数来向客户程序发送应答
			send(ClientSocket,Buffer,RecvNum,0);
		}
	}

	closesocket(ClientSocket);
	closesocket(ListenSocket);
	WSACleanup();
	return 0;
}


客户端代码:

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

#include "stdafx.h"
#include <WinSock2.h>
#pragma comment(lib,"Ws2_32.lib")

int _tmain(int argc, _TCHAR* argv[])
{
	WSADATA wsadata;
	WSAStartup(0x0202,&wsadata);

	SOCKET SeverSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	sockaddr_in SeverAddr;
	memset(&SeverAddr,0,sizeof(sockaddr_in));
	SeverAddr.sin_family=AF_INET;
	SeverAddr.sin_port=htons(7070);
	SeverAddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");

	int r=connect(SeverSocket,(sockaddr *)&SeverAddr,sizeof(sockaddr));
	if(r==0)
	{
		printf("连接服务器成功!\n");
	}
	else
	{
		printf("连接服务器失败!\n");
		goto EXIT;
	}

	char Buffer[999];
	int RecvNum=0;
	while(1)
	{
		scanf("%s",Buffer);
		if(strcmp(Buffer,"x")==0)
		{
			break;
		}

		send(SeverSocket,Buffer,strlen(Buffer)+1,0);

		RecvNum=recv(SeverSocket,Buffer,999,0);
		if((RecvNum==0)||(RecvNum==SOCKET_ERROR))
		{
			printf("服务器断开连接或连接异常断开\n");
			break;
		}
		else
		{
			printf("%s\n",Buffer);
		}
	}

EXIT:
	closesocket(SeverSocket);
	WSACleanup();

	getchar();
	return 0;
}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值