ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

基于UDP实现的socket通信

2019-07-20 09:06:27  阅读:521  来源: 互联网

标签:UDP socket int 通信 saddr sockfd include buff


文章目录

【1】TCP和UDP的区别

Tcp 是 面向连接的 可靠的 流式服务
所以Tcp 需要进行三次握手建立连接后,才可以传输用户数据,可靠性是通过应答确认、超时重传机制等保证,还有滑动窗口来进行流量控制。
Udp 是 无连接 不可靠 数据报服务
所以UDP不需要进行三次握手来建立连接,直接发送数据,不保证可靠交付,不管对方收到还是没有收到。

【2】TCP和UDP的编程流程

在这里插入图片描述在这里插入图片描述

【3】函数sendto()和recvfrom()

函数原型:

#include <sys/types.h>
#include <sys/socket.h>

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
            struct sockaddr *src_addr, socklen_t *addrlen);
            
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
           const struct sockaddr *dest_addr, socklen_t *addrlen);

参数:
sockfd :标识一个已连接套接口的描述字
buf :接收数据缓冲区/发送数据缓冲区
len :缓冲区长度
flags :调用操作方式,flags参数以及返回值的含义与send/recv系统调用的flags参数及返回值相同
src_addr指针指向装有源地址的缓冲区(若是面向连接的socket编程,则可以省略这个参数,因为已经建立了连接,所以我们已经知道接收谁的数据,知道它的地址)
dest_addr指针指向装有目标地址的缓冲区(若是面向连接的socket编程,则可以省略这个参数,因为已经建立了连接,所以我们已经知道要发送给谁,并且知道他的地址)
addrlen指针 :指向地址缓冲区长度值

【4】代码示例

实现客户端服务器交互
server.c

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>

int main()
{
	int sockfd = socket(AF_INET,SOCK_DGRAM,0);
	assert(sockfd != -1 );
	
	//指明地址信息
	struct sockaddr_in saddr,caddr;
	memset(&saddr,0,sizeof(saddr));
	saddr.sin_family = AF_INET;
	//普通数字可以用htons()函数转换成网络数据格式的数字)
	saddr.sin_port = htons(6000);
	//将点分十进制的IP地址转化为二进制
	saddr.sin_addr.s_addr = inet_addr("192.168.31.225");
	//绑定地址信息
	int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
	assert(res != -1);
    
    //	UDP不用listen监听
	while(1)
	{
        char buff[128]={0};
		int len = sizeof(caddr);

        //	UDP使用recvform接收数据
        //	UDP不用accept
		int n = recvfrom(sockfd,buff,127,0,(struct sockaddr*)&caddr,&len);
		
		assert(n!=-1);
		//	输出运行结果
		printf("ip=%s,port=%d,buff=%s\n",inet_ntoa(caddr.sin_addr),ntohs(caddr.sin_port),buff);
	
    	//	UDP使用sendto发送数据
        sendto(sockfd,"OK",2,0,(struct sockaddr*)&caddr,sizeof(caddr));
	}
    close(sockfd);
    exit(0);
}


client.c

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>

int main()
{
	int sockfd = socket(AF_INET,SOCK_DGRAM,0);
	assert(sockfd != -1 );

	struct sockaddr_in saddr;
	memset(&saddr,0,sizeof(saddr));
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(6000);
	saddr.sin_addr.s_addr = inet_addr("192.168.31.225");

	while(1)
	{
		char buff[128] = {0};
		printf("input:\n");
		fgets(buff,128,stdin);
		if(strncmp(buff,"end",3) ==0 )
		{
			break;
		}
		//	UDP使用sendto发送数据
		sendto(sockfd,buff,strlen(buff),0,(struct sockaddr*)&saddr,sizeof(saddr));
		memset(buff,0,128);
        int len=sizeof(saddr);
        //	UDP使用recvform接收数据
		recvfrom(sockfd,buff,127,0,(struct sockaddr*)&saddr,&len);
        printf("buff=%s\n",buff);
	}
	close(sockfd);
    exit(0);
}

运行结果:
在这里插入图片描述

标签:UDP,socket,int,通信,saddr,sockfd,include,buff
来源: https://blog.csdn.net/weixin_39411321/article/details/96486567

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

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

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

ICode9版权所有