Linux网络编程基础(二)
来源:互联网 发布:js 全局变量 丢失属性 编辑:程序博客网 时间:2024/06/05 09:05
前面讲了TCP的编程流程,这里接着来讲UDP的编程流程。讲完UDP的编程流程然后再说两者的区别。
UDP的编程流程:同样也要分为服务器端和客户端。
1、服务器端,如下图:
2、客户端,如下图:
现在描述一下UDP编程的接收和发送消息的系统调用函数recv from()和send to():
#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);/*recvfrom读取sockfd上的数据,buf和len参数分别指定读缓冲区的位置和大小。因为UDP是无连接通信,所以我们每次读取数据都需要获取发送端的socket地址,即参数src_addr所指的地址,addrlen参数则指定该地址的长度。*/ssize_t sendto(int sockfd,const void* buf,size_t len,int flags, const struct sockaddr* dest_addr,socklen_t addrlen);/*sendto往sockfd上写入数据,buf和len参数分别指定写缓冲区的位置和大小,dest_addr参数指定接收端的socket地址,addrlen参数则指定该地址的长度。*/
recvfrom/sendto系统调用也可以用于面向连接的socket的数据读写,只需把最后两个参数设置为NULL以忽略发送端/接收端的socket地址。
2、流式服务(TCP)和数据报服务(UDP)的区别
此处引用一本书里图作以说明
注:
(1) TCP接收缓冲区会对接收到的TCP报文进行重排、整理再交付给应用层,即流
式服务 sebd() n次 recv() 一次;
(2) 数据报服务具有“不可靠”的特点,需要上层协议来处理数据和超时重传。
3、UDP编程举例
服务器端ser.c
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<assert.h>#include<unistd.h>#include<sys/socket.h>#include<sys/types.h>#include<arpa/inet.h>void main(){ int sockfd = socket(AF_INET,SOCK_DGRAM,0); assert(sockfd != -1); struct sockaddr_in ser,cli; ser.sin_family = AF_INET; ser.sin_port = htons(6000); ser.sin_addr.s_addr = inet_addr("127.0.0.1"); int res = bind(sockfd,(struct sockaddr*)&ser,sizeof(ser)); assert(res != -1); while(1) { char buf[128] = {0}; int len = sizeof(cli); recvfrom(sockfd,buf,127,0,(struct sockaddr*)&cli,&len); printf("ip::%s\nport::%d\ndata::%s\n", inet_ntoa(cli.sin_addr), ntohs(cli.sin_port),buf); sendto(sockfd,"I know",strlen("I know"),0, (struct sockaddr*)&cli,len); } close(sockfd);}
客户端 cli.c
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <assert.h>#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>void main(){ int sockfd = socket(AF_INET,SOCK_DGRAM,0); assert(sockfd != -1); struct sockaddr_in ser,cli; ser.sin_family = AF_INET; ser.sin_port = htons(6000); ser.sin_addr.s_addr = inet_addr("127.0.0.1"); sendto(sockfd,"heelo world",11,0, (struct sockaddr*)&ser,sizeof(ser)); char buf[128] = {0}; recvfrom(sockfd,buf,127,0,NULL,NULL); printf("OK\n"); close(sockfd);}
阅读全文
0 0
- linux网络编程基础(二)
- Linux网络编程基础(二)
- Linux网络编程基础(二)
- Linux网络编程基础二
- 网络编程基础(二)
- Linux——网络编程基础(二)
- linux网络编程基础API(二)
- Linux网络编程(二)
- Linux网络编程(二)
- 网络编程基础<二>
- Linux--网络编程(二)UDP编程
- Java基础—网络编程(二)
- Java基础-网络编程(二)
- 套接字网络编程基础(二)
- Linux网络编程(二)
- Linux网络编程(二)
- Linux网络编程二
- linux网络编程基础
- AE调用 AddField 对 COM 组件的调用返回了错误 HRESULT E_FAIL。-2147467259
- 单链表环入口另类找法,很好理解
- Intro to Bilinear Maps
- 1.Java实现各种排序
- 文档就绪事件--document.ready和onload的区别
- Linux网络编程基础(二)
- C++函数的返回值(中)
- 过路费,白书P331UVa10537(dijkstra算法逆推应用,最短路径保存)
- Java 入门
- Maven 的pom.xml文件结构之基本配置parent和继承结构
- 技术人员的发展之路
- day6 类和集合
- [模板]平衡树treap
- POJ 2653 (判断线段相交)