Linux IPC udp/ip socket 编程
模型

#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 bind
sa_family_t sa_family;
char sa_data[14];
}
struct sockaddr_in{ //准备网络通信的通信地址 //$man in.h
sa_family_t sin_family; //协议族, 就是socket()的domain的AF_INET
in_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 | |
| TCP/IP | send();recv() |
| UDP/IP | recvfrom();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. 创建socket
int 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. 关闭socket
res=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;
}
Linux IPC udp/ip socket 编程的更多相关文章
- Linux IPC tcp/ip socket 编程
模型 #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include < ...
- Linux下的C Socket编程 -- 获取对方IP地址
Linux下的C Socket编程(二) 获取域名对应的IP地址 经过上面的讨论,如果我们想要连接到远程的服务器,我们需要知道对方的IP地址,系统函数gethostbyname便能够实现这个目的.它能 ...
- Linux下的C Socket编程 -- 简介与client端的处理
Linux下的C Socket编程(一) 介绍 Socket是进程间通信的方式之一,是进程间的通信.这里说的进程并不一定是在同一台机器上也有可能是通过网络连接的不同机器上.只要他们之间建立起了sock ...
- ZT Linux系统环境下的Socket编程详细解析
Linux系统环境下的Socket编程详细解析 来自: http://blog.163.com/jiangh_1982/blog/static/121950520082881457775/ 什么是So ...
- Linux下的C Socket编程 -- server端的简单示例
Linux下的C Socket编程(三) server端的简单示例 经过前面的client端的学习,我们已经知道了如何创建socket,所以接下来就是去绑定他到具体的一个端口上面去. 绑定socket ...
- Linux下的C Socket编程 -- server端的继续研究
Linux下的C Socket编程(四) 延长server的生命周期 在前面的一个个例子中,server在处理完一个连接后便会立即结束掉自己,然而这种server并不科学啊,server应该是能够一直 ...
- Linux IPC udp/tcp/UNIX域 socket编程
UNIX域套接字本地通信即在socket第一个参数中选择AF_LOCAL,socket是BSD提出的一种适用于所有的情况的进程间通信的方式,虽然现在多用于网络通信,但是本机内的进程间通信也是没有问题的 ...
- linux系统UDP的socket通信编程3
我刚开始接触linux下的socket编程,边抄边理解udp socket编程,我的疑问是server不指定IP地址,client的目标IP地址是127.0.0.1,这样就可以通信吗?在同一主机下是不 ...
- TCP和UDP的Socket编程实验
Linux Socket 函数库是从 Berkeley 大学开发的 BSD UNIX 系统中移植过来的.BSD Socket 接口是在众多 Unix 系统中被广泛支持的 TCP/IP 通信接口,Lin ...
随机推荐
- Eclipse保存文件时自动格式化代码
实现效果:Ctrl+S会自动格式化并保存代码. 应用上图所示效果之后,在每次对Eclipse保存的时候都会实现自动格式化代码. 1. Fomated All lines,格式化该文件的所有代码:还是 ...
- 框架Spring笔记系列 一 基础
主题:Spring 1.什么样的问题,使得Spring框架应用而生?使用Spring解决了那些问题? 2.
- Scalaz(16)- Monad:依赖注入-Dependency Injection By Reader Monad
在上一篇讨论里我们简单的介绍了一下Cake Pattern和Reader Monad是如何实现依赖注入的.主要还是从方法上示范了如何用Cake Pattern和Reader在编程过程中解析依赖和注入依 ...
- [转]精通JS正则表达式
原文路径:http://www.jb51.net/article/25313.htm 正则表达式可以: •测试字符串的某个模式.例如,可以对一个输入字符串进行测试,看在该字符串是否存在一个电话号码模式 ...
- C#如何实现一个简单的流程图设计器
以前看过不少Window Form开发的流程图设计器,支持节点拖放,非常方便即可设计出很美观的流程图,作为一个程序员,对其内部实现原理一直很好奇,感叹有朝一日自己如果可以开发一款类似的软件那是多么让人 ...
- 基于 jQuery 实现的精致作品集图片导航效果
今天,我们要用 jQuery 来创建一个作品集图像的导航模板.我们的想法是,以分组的方式显示一组作品集,并通过二维的方式(水平/垂直)来浏览.任一箭头或当前图像下方的小盒子可以作为导航使用. 在线演示 ...
- 简直要逆天!超炫的 HTML5 粒子效果进度条
我喜欢粒子效果作品,特别是那些能够应用于实际的,例如这个由 Jack Rugile 基于 HTML5 Cavnas 编写的进度条效果.看着这么炫的 Loading 效果,即使让我多等一会也无妨:)你呢 ...
- 移动端H5-第一课css篇
1.移动端开发视窗口的添加 h5端开发下面这段话是必须配置的 meta name="viewport" content="width=device-width, init ...
- 简单的gulpfile.js参数配置
这里gulp安装和模块安装我就不提了,先简单写一些配置函数 for example /** * Created by yumeiqiang on 16/7/26. */var gulp = requi ...
- Sharepoint学习笔记—习题系列--70-576习题解析 -(Q45-Q48)
Question 45 You are designing a branding strategy for a customer with a new SharePoint 2010 server f ...