Windows网络编程

2 篇文章 0 订阅


1.先总结一些会用到的知识

 IP地址:IPV4中计算机都分配一个地址,该地址是一个32位的数值表示;客户端和服务器通信的时候需要指定一个IP地址和端口。
      IP地址一般是用“Internet点分表示a.b.c.d一样指定的,每一个字母代表一个字节的数字(十进制、八进制
          或十六进制)从左到右分配了一个无符号长整数4字节。 

unsigned long inet_addr(_In_ const char *cp) 一个点分IP地址转换成一个32的无符号长整数。
网络字节序:TCP/IP协议中规定好的数据表示方法,顺序采用big endian排序方式;
主机字节序:主机表示数据的方法,不同的操作系统字节序不同,有big endian,有的是little endian ;若是主机字节序与网络字节序不同,则需 
            要转换成一致的字节序;
转换字节序用到的函数:
                  网络字节序——主机字节序                      主机字节序——网络字节序

ntohl htonl WSANtohl WSAHtonl

ntohs htons

WSANtohs WSAHtons

SOCKADDR_IN结构:来指定IP地址和服务端口信息。

struct sockaddr_in

{

    short  sin_family; //    协议族   一般为AF_INET

    u_short  sin_port;     //   端口号,必须使用网络字节序

     struct   in_addr  sin_addr; //IP地址信息

     char     sin_zero[8]; //为了使sockaddr与sockaddr_in两个数据结构保持大小相同而保留的空字节

}

2.面向连接的TCP协议编程

1)服务器端程序

#include<iostream>
#include<WinSock2.h>
#include<stdio.h>
 
#pragma comment(lib,"Ws2_32")//添加库文件
 
using namespace std;
 
int main()
{
	//1.创建套接字(socket)
	WORD version =MAKEWORD(2,2);//先确定使用套接字的版本
	WSADATA wdata;
	int erro =WSAStartup(version,&wdata);//启动套接字
	if(erro!=0)
	{
		cout<<"套接字启动失败!"<<endl;
 
	}
	if((LOBYTE(wdata.wVersion)!=2)||(HIBYTE(wdata.wVersion)!=2))//如果版本不对,清除当前的套接字
	{
		WSACleanup();
	}
	SOCKET sockSer=socket(AF_INET,SOCK_STREAM,0);//指定协议族、套接字类型(流式套接字)、协议初始化
 
        //2.将套接字绑定到一个本地地址和端口上(bind)
 
	//指定服务器IP
	SOCKADDR_IN Servaddr;          
	Servaddr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//IP
	Servaddr.sin_family=AF_INET;//协议族,必须是AF_INET
	Servaddr.sin_port=htons(6000);//IP端口
 
	bind(sockSer,(sockaddr*)&Servaddr,sizeof(sockaddr));//将socket与本地的一个IP关联
 
//3.将套接字设置成监听模式,准备接收客户的请求(listen)
	listen(sockSer,10);
 
 
//4.等待客户请求到来,当请求到来后,接收连接请求,返回一个新的对应于此次连接的套接字(accept)
 
 
	SOCKADDR_IN clientadd;
	int len = sizeof(sockaddr);
 
	while(1)
	{
		Sleep(10000);
		char sendbuf[100];
		SOCKET  sockCon =accept(sockSer,(sockaddr*)&clientadd,&len);//返回一个新的对应于此次连接的套接字,将地址和端口空出来
 
//5.用返回的套接字和客户端进行通信(send/recv)
		
		sprintf(sendbuf,"This is: Server!");
		send(sockCon,sendbuf,strlen(sendbuf)+1,0);//发送用连接的套接字,不能用正在监听的那个套接字
 
		char recvbuf[100];
		recv(sockCon,recvbuf,100,0);
		cout<<"Server Receive :"<<recvbuf<<endl;
		closesocket(sockCon);
 
	}
	cout<<"a: "<<endl;
	system("pause");
	return 0;
 
 
}

 

2.客户端的程序

    

#include<WinSock2.h>

#include<iostream>

 

 

#pragma comment(lib,"Ws2_32")

 

using namespace std;

 

int main()

{

//客户端

 //1.创建套接字

WSADATA wsd;

wsd.wVersion=MAKEWORD(2,2);//确定套接字的版本

int erro;

erro=WSAStartup(wsd.wVersion,&wsd);

if(erro!=0)

{

  cout<<"套接字启动失败!"<<endl;

}

if((LOBYTE(wsd.wVersion)!=2)||(HIBYTE(wsd.wVersion)!=2))

{

    cout<<"套接字版本错误!"<<endl;

WSACleanup();

}

SOCKET Clientsocket = socket(AF_INET,SOCK_STREAM,0);

 

SOCKADDR_IN  Servadd;

Servadd.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");

Servadd.sin_family=AF_INET;

Servadd.sin_port=htons(6000);

 

//2.向服务器发送连接请求(connect)

connect(Clientsocket,(sockaddr*)&Servadd,sizeof(sockaddr));//套接字,服务器IP地址,地址结构体的长度

 

//3.与服务器通信(send/recv)

char sendbuf[100],recvbuf[100];

  while(1)

  {

  Sleep(10000);

     recv(Clientsocket,recvbuf,100,0);

 cout<<"receive :"<<recvbuf<<endl;

 send( Clientsocket,"this is client",strlen("this is client")+1,0);

     

 closesocket(Clientsocket);

// WSACleanup();

  

  }

 

system("pause");

return 0;

}

 

以上是使用TCP协议的简单编程,TCP是面向连接的通信,是协议,UDP是无连接通信,几乎是基于消息的因此在接收函数的调用必须提供一个足够大的缓冲空间,如果缓冲区不够大,接收调用会失败,出现错误WSAEMSGSIZE缓冲区填满,未接收完的数据会丢弃

//Udp服务器
#include<WinSock2.h>
#include<iostream>

#pragma comment(lib,"Ws2_32")
using  namespace std;

int main()
{
	//服务器端
	//1.创建套接字
    DWORD wversion;
	wversion =MAKEWORD(2,2);
	WSADATA wsa;
	wsa.wVersion=wversion;
	int erro=0;
	erro= WSAStartup(wversion,&wsa);
	if(erro!=0)
	{
	    cout<<"套接字启动失败!"<<endl;
	}
	if((LOBYTE(wsa.wVersion)!=2)||(HIBYTE(wsa.wVersion)!=2))
	{
	  cout<<"套接字版本错误!"<<endl;
	  WSACleanup();
	}
	SOCKET socket_uServer = socket(AF_INET,SOCK_DGRAM,0);//协议族、格式、初始化
	
	//2.绑定套接字
	SOCKADDR_IN SockAddr,sendaddr; 
	SockAddr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
	SockAddr.sin_family=AF_INET;
	SockAddr.sin_port=htons(7000);
	int len = sizeof(sockaddr);
	bind(socket_uServer,(sockaddr*)&SockAddr,len);

	//3.等待数据连接
	char recvbuf[100];
	int sendlen= sizeof(sendaddr);
	recvfrom(socket_uServer,recvbuf,100,0,(sockaddr*)&sendaddr,&sendlen);
	cout<<"recv : "<<recvbuf<<endl;
	cout<<"the IP is"<<inet_ntoa(sendaddr.sin_addr)<<endl;
	char sendbuf[]="I received your message \0";
	sendto(socket_uServer,sendbuf,strlen(sendbuf),0,(sockaddr*)&sendaddr,sizeof(sendaddr));
	closesocket(socket_uServer);
	WSACleanup();
	system("pause");
	return 0;
}
UDP客户端

#include<WinSock2.h>
#include<iostream>

#pragma comment(lib,"Ws2_32")
using  namespace std;

int main()
{
	//服务器端
	//1.创建套接字
    DWORD wversion;
	wversion =MAKEWORD(2,2);
	WSADATA wsa;
	wsa.wVersion=wversion;
	int erro=0;
	erro= WSAStartup(wversion,&wsa);
	if(erro!=0)
	{
	    cout<<"套接字启动失败!"<<endl;
	}
	if((LOBYTE(wsa.wVersion)!=2)||(HIBYTE(wsa.wVersion)!=2))
	{
	  cout<<"套接字版本错误!"<<endl;
	  WSACleanup();
	}
	SOCKET socket_uClient = socket(AF_INET,SOCK_DGRAM,0);//协议族、格式、初始化
	
	
	//2.发送数据
	SOCKADDR_IN SockAddr,sendaddr; 
	SockAddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
	SockAddr.sin_family=AF_INET;
	SockAddr.sin_port=htons(7000);
	int len = sizeof(sockaddr);
	
	char sendbuf[]="I received ";
	sendto(socket_uClient,sendbuf,strlen(sendbuf)+1,0,(sockaddr*)&SockAddr,sizeof(SockAddr));
	char recvserbuf[100];
	recvfrom(socket_uClient,recvserbuf,100,0,(sockaddr*)&SockAddr,&len);
	cout<<"recv from server: "<<recvserbuf<<endl;
	closesocket(socket_uClient);
	WSACleanup();
	system("pause");
	return 0;
}

这些是最基础,最简单的编程,实际应用中要更加复杂,慢慢 结。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值