【windows socket+UDP服务器客户端】

Windows Socket+UDP服务器客户端


      Winsock 是 Windows下套接字标准
         
         1.UDP socket编程

         UDP(用户数据报协议)是一个无连接,不可靠的数据传输,其特点是简单,快捷。相比与TCP,UDP不需要建立连接(不需connect、accept函数),数据发送接收之后,不需要终止连接。基于UDP的程序,避免了TCP运行的开销,在效率与速度上具有更好的表现。
         UDP是无连接的,可能会有数据的丢失,延迟,这些需要应用程序自己处理。
         
         2.UDP基本函数
          
创建socket
         SOCKET  socket (int af, int type, int protocol);
         第一个参数af:  表示族地址,网络编程一般使用AF_INET宏。
         第二个参数type:  表示连接类型,TCP可选面向连接SOCK_STREAM,UDP数据报SOCK_DGRAM。
         第三个参数protocol:  表示协议,在使用AF_INET族地址UDP连接,设为IPPROTO_UDP。
绑定socket:
         int  bind(SOCKET s, const struct sockaddr *saddr,int namelen);
         第一个参数:  需要绑定的socket。
         第二个参数:  对应AF_INET,使用struct sockaddr_in包含协议,IP,端口等信息。
         第三个参数:  对应AF_INET,使用struct sockaddr_in结构大小。
         该函数将socket与协议,IP地址,Port端口号绑定起来,相对于给socket“命名”唯一的标识,这样其他的进程就可以通过这个标识找到这个socket。
发送数据
         int  sendto(SOCKET s, const char  *buf,  int len,
                              int flags, const struct sockaddr  *to, int tolen);
         第一个参数:  socket为对方的socket。
         第二个参数:  发送数据的缓冲区。
         第三个参数:  数据缓冲区大小。
         第四个参数:  紧急状态,一般这为0。
         第五个参数:  可选,对应AF_INET,对方IP,端口等socket地址标识sockaddr_in。
         第六个参数:  可选,对应AF_INET,使用sockaddr_in结构大小。
         该函数用于UDP发送数据。
接收数据
         int  recvfrom(SOCKET s, char *buf, int len, 
                                  int flags, struct sockaddr *from, int *fromlen );          
         第一个参数:  socket为对方的socket。
         第二个参数:  接收数据的缓冲区。
         第三个参数:  数据缓冲区大小。
         第四个参数:  紧急状态,一般这为0。
         第五个参数:  可选,对应AF_INET,返回对方IP,端口等socket地址标识sockaddr_in。
         第六个参数:  可选,对应AF_INET,使用sockaddr_in结构大小。
         该函数用于UDP接收数据。
绑定socket
         int  bind(SOCKET s, const struct sockaddr *saddr,int namelen);
         第一个参数:  需要绑定的socket。
         第二个参数:  对应AF_INET,使用struct sockaddr_in包含协议,IP,端口等信息。
         第三个参数:  对应AF_INET,使用struct sockaddr_in结构大小。
         该函数将socket与协议,IP,端口号绑定起来,相对于给socket“命名”唯一的标识,这样其他的进程就可以通过这个标识找到这个socket。
关闭套接字
          int  closesocket(SOCKET s);
          参数为socket。
          该函数用于关闭套接字。
          
          3.牛刀小试
          先在VC6.0运行服务器程序,再打开一个VC6.0运行客户端程序:
          UDPsever服务器等待来自客户端的信息,收到信息后打印出来,然后向客户端发送现在的时间。
          UDPclient客户端向服务器发送一个“Hello,server!”信息,然后接收来自服务器的时间信息并打印,重复三次。

运行效果:

UDP客户端程序:
#include
     
     
      
      
#include
      
      
       
       
#pragma comment(lib,"ws2_32.lib")
int main()
{
	WSADATA wsa;
	SOCKET serversoc;
	SOCKADDR_IN serveraddr;
	SOCKADDR_IN peeraddr;
	int peer_len=sizeof(peeraddr);
	char Recv_buf[64];
	//char *Server_IP="127.0.0.1";
	char *Send_data="Hello,server!";
	int Send_len=strlen(Send_data);
	int time_out=2000;    //接收超时
	int result;
    
	WSAStartup(WINSOCK_VERSION,&wsa);	//初始化WS2_32.DLL
    
	//命名协议,IP,端口
    serveraddr.sin_family = AF_INET;
	serveraddr.sin_port = htons(13);
	serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");

	if(serveraddr.sin_addr.s_addr==INADDR_NONE)
	{
			printf("不可用地址!\n");
			return -1;
	}
    
	//创建套接字
	serversoc = socket(AF_INET,SOCK_DGRAM,0);
	
    result = setsockopt(serversoc,SOL_SOCKET,SO_RCVTIMEO,(char*)&time_out,sizeof(time_out));
    for(int i=0;i<3;i++)
	{
	    //发送数据
		result = sendto(serversoc,Send_data,Send_len,0,(SOCKADDR *)&serveraddr,sizeof(serveraddr));

		//接收数据
		result = recvfrom(serversoc,Recv_buf,64,0,(SOCKADDR *)&peeraddr,&peer_len);
		if(result >= 0)
		{
			Recv_buf[result]= 0;
			printf("接收数据为:  %s \n",Recv_buf);
		}
	}
    closesocket(serversoc);
	WSACleanup();
    return 0;
}

      
      
     
     
UDP服务器程序:
#include
      
      
       
       
#include
       
       
        
        
#include
        
        
         
         
#pragma comment(lib,"ws2_32.lib")
int main()
{
	WSADATA wsa;
	WSAStartup(WINSOCK_VERSION,&wsa);	//初始化WS2_32.DLL

	SOCKET serversoc;
	SOCKET clientsoc;
	SOCKADDR_IN serveraddr;
	SOCKADDR_IN clientaddr;
	int client_len = sizeof(clientaddr);
	int server_len = sizeof(serveraddr);
	char *Send_data;
	int Send_len;
	char Recv_buf[64];
	int result;
	time_t nowtime;

	//命名协议,IP,端口
    serveraddr.sin_family = AF_INET;
	serveraddr.sin_port = htons(13);
	serveraddr.sin_addr.s_addr = INADDR_ANY;

	//创建socket
	serversoc = socket(AF_INET,SOCK_DGRAM,0);
	

	//绑定socket
	result=bind(serversoc, (SOCKADDR *)&serveraddr, server_len);
	if(result==SOCKET_ERROR)
	{
		printf("套接字绑定失败!\n");
		closesocket(serversoc);
		return -1;
	}

	printf("Server is running.....\n");

	clientsoc = socket(AF_INET,SOCK_DGRAM,0);
	while(1)
	{   
		//接收数据
		result = recvfrom(serversoc,Recv_buf,64,0,(SOCKADDR *)&clientaddr,&client_len);
		if(result >= 0)
		{
			Recv_buf[result]= 0;
			printf("接收数据为:  %s \n",Recv_buf);
		
		    //发送数据
			nowtime=time(0);
			Send_data=ctime(&nowtime);
			Send_len=strlen(Send_data);
	     	result = sendto(clientsoc,Send_data,Send_len,0,(SOCKADDR *)&clientaddr,sizeof(clientaddr));
			printf("Server is running.....\n");
		}
	}

	closesocket(serversoc);
	WSACleanup();
	return 0;
}

        
        
       
       
      
      


  • 8
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
UDP(User Datagram Protocol)是一种面向无连接的传输层协议,它不保证数据传输的可靠性,但传输效率高,适用于对实时性要求较高、数据传输量较小的场景。在使用UDP进行通信时,需要通过socket API来实现数据的发送和接收。 UDP客户端服务器之间的通信过程可以分为以下几个步骤: 1. 创建UDP socket客户端服务器端都需要创建一个UDP socket,用于发送和接收数据。可以使用socket()函数创建socket,其参数指定协议族、socket类型和协议编号。 2. 绑定socket服务器端需要将socket绑定到一个本地地址上,这样客户端才能够通过该地址和端口号来访问服务器。可以使用bind()函数将socket与一个IP地址和端口号绑定。 3. 发送数据 客户端可以使用sendto()函数向服务器发送数据,其中需要指定目标地址和端口号,以及要发送的数据内容。发送时,数据会被拆分成若干个数据包进行传输。 4. 接收数据 服务器端可以使用recvfrom()函数从客户端接收数据,其中需要指定一个缓冲区来存储接收到的数据,以及发送方的地址和端口号。由于UDP是无连接的,因此接收到的数据包可能不是按照发送的顺序到达的。 5. 关闭socket 通信结束后,需要使用close()函数关闭socket,释放相关的资源。 UDP通信的优点是传输效率高,适用于对实时性要求较高、数据传输量较小的场景,但缺点是不保证数据传输的可靠性,因此在数据传输过程中可能会出现丢包、重复等问题。为了保证数据传输的可靠性,可以使用TCP协议进行通信。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值