模型

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
//服务器:    socket()              //创建socket
struct sockaddr_in    //准备通信地址
bind()                //绑定socket和addr
sendto()/recvfrom     //进行通信
close()               //关闭socket//客户端:socket()              //创建socket:
//准备通信地址:服务器的地址
sendto()/recv()       //进行通信:
close()               //关闭socket:

socket()

//创建网络端点,返回socket文件描述符,失败返回-1设errno
int socket(int domain, int type, int protocol);

domain :协议族(protocol family)(网络通讯(IP)还是本地通讯(xxx.socket))

  • AF_INET用于实现给予ipv4网络协议的网络协议
    type :协议(TCP还是UDP)
  • SOCK_DGRAM //数据报套接字, 实现包括但不限于UDP协议, which is不可靠,无连接的数据报通信方
    protocol: 特殊协议, 一般给0

准备通信地址:

struct sockaddr{    //主要用于函数的形参类型, 很少定义结构体变量使用, 叫做通用的通信地址类型//$man bindsa_family_t     sa_family;char            sa_data[14];
}
struct sockaddr_in{ //准备网络通信的通信地址   //$man in.hsa_family_t sin_family;     //协议族, 就是socket()的domain的AF_INETin_port_t       sin_port;   //端口号struct in_addr  sin_addr;   //IP地址,//当前网段的最大ip地址是广播地址,即,xxx.xxx.xxx.255。//255.255.255.255在所有网段都是广播地址
}
struct in_addr{ in_addr_t   s_addr;     //整数类型的IP地址
}

bind()

//把通信地址和socket文件描述符绑定,用在服务器端,成功返回0,失败返回-1设errno
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

sockfd: socket文件的fd(returned by socket())
addr: 需要强制类型转换成socketaddr_un或soketaddr_in, 参见上
addrlen: 通信地址的大小, 使用sizeof();

sendto()

//向指定的socket和相应的地址发送消息,成功返回实际发送数据的大小,失败返回-1设errno
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);

dest_addr:目标地址(收件人信息)
addrlen: 目标地址的大小

ANote

  • send(sockfd, buf, len, flags);等价于 sendto(sockfd, buf, len, flags, NULL, 0);
  • recv()/ send()表示通过sockfd收发数据, 因为tcp下, 收发之前sockfd已经和相应的地址连接了,所以不需要指定收发谁的/给谁, 但是udp因为收发时没有连接, 所以需要指定

recvfrom()

//从指定的socket和相应的地址接受消息,并提供来电显示的功能,成功返回实际接收的数据大小,失败返回-1设errno
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);

src_addr: 结构体指针, 用于保存数据发送方的通信地址
addrlen: 指针类型, 用于保存发送方的地址大小

Note:

  • recv(sockfd, buf, len, flags); 等价于 recvfrom(sockfd, buf, len, flags, NULL, 0);
  • accept() and recvfrom() 后面的参数是用来提供来电显示的
  • 一个server对应多个client
  • server可以不知道client的地址, 但是client得知道server的地址
  • send data 一定要知道对方地址
  • receive data不需要知道对方地址
  • TCP/IP的socket都是SOCK_STREAM的,全程连接,通过socket就能找到对方地址, send data的话,直接丢给socket就行
  • UDP/IP的socket是SOCK_DGRAM的,不全程连接,不能通过socket找到对方,send data的话,server中需要使用recvfrom()来知道client的地址, 所以肯定要sendto();client本来就知道server的地址, 直接sendto()
  • recvfrom()的唯一意义就是在udp-server中配合sendto()使用
  • 因为不能通过socket找到对方, 只要是udp发消息, 就得通过sendto()
server client
TCP/IP send();recv() send();recv()
UDP/IP recvfrom();sendto() recv();sendto()

例子-一对一的upd/ip协议的服务器模型

//udp/ip server 五步走
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
int main(){//1. 创建socketint sockfd=socket(AF_INET,SOCK_DGRAM,0);if(-1==sockfd)perror("socket"),exit(-1);//2. 准备通信地址struct sockaddr_in addr;addr.sin_family=AF_INET;addr.sin_port=htons(8888);addr.sin_addr.s_addr=inet_addr("176.43.11.211");//3. 绑定socket和通信地址int res=bind(sockfd,(struct sockaddr*)&addr,sizeof(addr));if(-1==res)perror("bind"),exit(-1);printf("bind success\n");//4. 进行通信char buf[100]={0};struct sockaddr_in recv_addr;       //为使用recvfrom得到client地址做准备, 最终为sendto()做准备socklen_t len=sizeof(recv_addr);res=recvfrom(sockfd,buf,sizeof(buf),0,(struct sockaddr*)&recv_addr,&len);if(-1==res)perror("recvfrom"),exit(-1);char* ip=inet_ntoa(recv_addr.sin_addr);             //将recvfrom获得client地址转换成点分十进制字符串printf("data received from client :%s is:%d\n",ip,res); res=sendto(sockfd,"I received",sizeof("I received"),0,(struct sockaddr*)&recv_addr,len);//使用recvfrom获得的client地址if(-1==res)perror("sendto"),exit(-1);//5. 关闭socketres=close(sockfd);if(-1==res)perror("close"),exit(-1);printf("close success\n");return 0;
}
//udp/ip client
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>  //close()
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
int main(){int sockfd=socket(AF_INET,SOCK_DGRAM,0);if(-1==sockfd)perror("socket"),exit(-1);printf("create socket succesfully\n");struct sockaddr_in addr;addr.sin_family=AF_INET;addr.sin_port=htons(8888);addr.sin_addr.s_addr=inet_addr("176.43.11.211");    //这个是server的地址, 虽然没有connect, which means 不能通过socket找到这个地址, 但是我们还是知道这个地址的, sendto()是可以直接用的int res=sendto(sockfd,"hello",sizeof("hello"),0,(struct sockaddr*)&addr,sizeof(addr));if(-1==res)perror("sendto"),exit(-1);printf("data sent size:%d\n",res);char buf[100]={0};res=recv(sockfd,buf,sizeof(buf),0);if(-1==res)perror("recv"),exit(-1);printf("data received from server:%s\n",buf);res=close(sockfd);if(-1==res)perror("close"),exit(-1);return 0;
}

转载于:https://www.cnblogs.com/xiaojiang1025/p/5950461.html

Linux IPC udp/ip socket 编程相关推荐

  1. Java TCP/IP Socket 编程 笔记

    http://jimmee.iteye.com/blog/617110 http://jimmee.iteye.com/category/93740 Java TCP/IP Socket 编程 笔记( ...

  2. TCP与UDP在socket编程中的区别

    TCP与UDP在socket编程中的区别 一.TCP与UDP的区别 基于连接与无连接 对系统资源的要求(TCP较多,UDP少) UDP程序结构较简单 流模式与数据报模式 TCP保证数据正确性,UDP可 ...

  3. tcp与udp的socket编程,udp代码实现客户端服务端,tcp代码实现客户端服务端(单线程、多线程、多进程分别实现),三次握手

    socket编程 网络字节序 定义 为什么网络数据需要转换为网络字节序? Udp协议 Tcp协议 Udp的socket编程 编程流程 接口 创建套接字 绑定地址信息 发送 接收 关闭 主机字节序转换成 ...

  4. 基于 UDP 的 Socket 编程

    基于 UDP 的 Socket 编程 UDP的定义 •UDP 是用户数据报协议,提供的是无连接.不可靠信息传送服务.Java 主要提供了两个类来实现基于 UDP 的 Socket 编程. UDP编程的 ...

  5. linux下的c socket编程(4)--server端的继续研究

    linux下的C socket编程(4) 延长server的生命周期: 在前面的一个个例子中,server在处理完一个链接之后便会立即结束掉自己,然而这种server并不科学,server因该使能够一 ...

  6. Linux IPC udp/tcp/UNIX域 socket编程

    UNIX域套接字本地通信即在socket第一个参数中选择AF_LOCAL,socket是BSD提出的一种适用于所有的情况的进程间通信的方式,虽然现在多用于网络通信,但是本机内的进程间通信也是没有问题的 ...

  7. 【Linux】详解socket编程接口

    socket编程接口详解 1. socket常见API 2. IPv4协议的地址信息结构:sockaddr_in结构体 2.1 sockaddr结构体 2.2 in_addr结构体 2.3 socka ...

  8. TCP 和 UDP 在socket编程中的区别

    (网络收集) 一.TCP与UDP的区别 基于连接与无连接  对系统资源的要求(TCP较多,UDP少)  UDP程序结构较简单  流模式与数据报模式  TCP保证数据正确性,UDP可能丢包  TCP保证 ...

  9. linux网络编程之Socket编程

    (1)socket套接字 1)在linux环境下,socket用于表示进程间网络通信的特殊文件类型,其本质是内核借助缓冲区形成的伪文件(不占磁盘空间,除此之外还有二进制文件,管道,字符文件). 2)伪 ...

  10. 基于TCP/UDP的socket编程

    基于TCP(面向连接)的socket编程 服务器端顺序:  1. 创建套接字(socket)  2. 将套接字绑定到一个本地地址和端口上(bind)  3. 将套接字设为监听模式,准备接收客户请求(l ...

最新文章

  1. 003_html编辑器
  2. php浏览器类型检测工具,php检测客户端浏览器类型的简单示例
  3. caffe源码解析—image_data_layer层
  4. MTK 驱动(72)---mtk Android如何调试recovery模块
  5. Sharding-Jdbc实现读写分离、分库分表,妙!
  6. jq 和java 多张图片_jQuery多个事件触发相同的功能
  7. 遍历目录下的所有文件-os.walk
  8. 数量场的等值面与矢量场的矢量线的一些基本的东西(写得不好)
  9. Android SDK Manager 中如果没有相应的镜像ARM XX Image
  10. 易语言-数据类型及其长度
  11. excel如何深度隐藏sheet呢?
  12. 数据库load data命令批量插入txt文件的数据
  13. SSD的三组成部件简介:主控芯片 闪存芯片 固件算法
  14. 喜报|中新赛克OceanMind独家赞助的DSE期刊被ESCI收录
  15. 产品运营:用户为什么要用你的产品
  16. Delphi与C#之父:技术理想架构开发传奇
  17. Android武器库
  18. Allegro基本元器件库路径
  19. 2层板天线50欧阻抗匹配
  20. 模型概念与数学和逻辑

热门文章

  1. 求一天的起始和结束(时间戳)和一个月的第一天和最后一天
  2. visual studio 2008试用版的评估期29天后结束 解决办法
  3. 如何理解CPU上下文切换(二)
  4. python学习笔记 day42 对数据表的操作---增删改查
  5. python基础 数据类型
  6. 【学习笔记】信息系统项目管理-项目採购管理-合同分类
  7. [大数据之Sqoop] —— 什么是Sqoop?
  8. 一些Python的惯用法和小技巧:Pythonic
  9. Unable to open log device '/dev/log/main' : No such file or directory it ...
  10. 十步让你成为一名优秀的 Web 开发人员