第8章基本UDP套接口编程
2011-11-06 15:41
281 查看
第8章基本UDP套接口编程
先介绍UDP的接受和发送函数ssize_t sendto(int fd,void* buff,size_t nbytes,int flag,sockaddr* addr,socklen_t *len) ssize_t recvfrom(int fd,void*buff,size_t nbytes,int flag,sockassr* addr,socklen_t *len)
fd 是打开的套接字
buff是发送数据,nbytes是数据的长度
int flag是设置的标志
addr是发送和接受的地址,len是地址的长度
返回值是读写成功的长度
UDP写一个长度为0的数据报是可以的。接受端接受到为0的数据报并不表示发送端发送的是FIN数据报
如果recvfrom的地址和地址长度都设置成NULL表示我们对地址和长度不感兴趣
UDP的回射程序:
贴代码:
服务器端
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <arpa/inet.h>
#include <string.h>
#define SERV_IP "127.0.0.1"
#define SERV_PORT 9999
#define MAX_LINE 1024
void dump_sock(int fd)
{
struct sockaddr_in recv_addr;
char recv_data[MAX_LINE+1] = {0};
int len = sizeof(recv_addr);
while(1)
{
int size = recvfrom(fd, recv_data, MAX_LINE, 0, (struct sockaddr*)&recv_addr,\
&len);
sendto(fd, recv_data, MAX_LINE, 0, (struct sockaddr*)&recv_addr, len);
printf("**********data************\n");
printf("%s\n",recv_data);
memset(recv_data, 0, MAX_LINE+1);
}
}
int main()
{
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if(fd == -1)
{
perror("socket execute fail\n");
return -1;
}
struct sockaddr_in addr;
int len = sizeof(addr);
addr.sin_family = AF_INET;
inet_pton(AF_INET, SERV_IP, &addr.sin_addr);
addr.sin_port = htons(SERV_PORT);
bind(fd,(struct sockaddr*)&addr, len);
dump_sock(fd);
return 0;
}
客户端:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #define SERV_IP "127.0.0.1" #define SERV_PORT 9999 #define MAX_LINE 1024 void dump_send(int fd, struct sockaddr_in* addr) { char send_data[MAX_LINE+1] = {0}; char recv_data[MAX_LINE+1] ={0}; int len = sizeof(structsockaddr_in); while(fgets(send_data, MAX_LINE,stdin) != NULL) { int size = sendto(fd,send_data,strlen(send_data), 0, (struct sockaddr*)addr,\ len); recvfrom(fd, recv_data,MAX_LINE, 0, NULL, NULL); write(STDOUT_FILENO,recv_data, strlen(recv_data)); } } int main() { struct sockaddr_in addr; int len = sizeof(addr); addr.sin_family = AF_INET; inet_pton(AF_INET, SERV_IP,&addr.sin_addr); addr.sin_port = htons(SERV_PORT); int fd = socket(AF_INET,SOCK_DGRAM, 0); if(fd == -1) { perror("socketfailed\n"); return -1; } dump_send(fd, &addr); exit(0); }
UDP是不建立连接的,只要客户端有数据发送,那个服务器就接受,只要客户端指定了服务器的ip和port就能把数据发送给服务器
服务器的api顺序是1 socket 2 bind 3 recvfrom 4sendto
客户端的调用顺序是1socket 2 sendto 3 recvfrom
客户端的ip和port如果没有绑定的话(bind),在sendto调用的时候,就会检测,如果没有,那么内核就会给该套接字临时生成一个ip和port来进行通讯
UDP的connect方法
UDP进行connect内核只是记录对方的ip和port,他们包含在传递给connect的sock_fd中。并且connect立即返回调用进程
已连接和未连接的套接字的区别:
1是已连接的套接字在发送数据的时候,不用再给他传递地址了,因为connect的时候指定了这个传递的ip和port,已连接的客户端,我们用write send来发送数据
2同理,已连接接受的时候,调用read或者recv了
3 已连接的UDP套接口,当出现异步错误的时候会传递给进程,但是未连接的UDP套接口是不接受错误信息的
任何其他的ip或者端口都不能把数据传递到该套接口,如果该主机上的接受到数据,但是这个数据报的目的端口没有进程,那么主机直接发送一个ICMP数据报
如果客户端想和多个服务器发送消息的话,就最好不要connect
对已连接的套接口调用多次connect的话,能够改变发送的服务器地址或port,如果connect的地址中的地址族是AF_UNSPEC的话,就直接断掉连接,并且返回一个FAFNOSUPPORT的错误代码
已连接和未连接的性能:
未连接发送2次数据:
连接套接口
发送数据1
断开套接口
连接套接口
发送数据
断开连接
已连接发送2次数据:
连接套接口
发送数据1
发送数据2
UDP不能进行流量控制,如果发送端处理的速度比接受端快很多的话,那么发送端就发的数据很多,当把该套接字的缓冲区写满的时候(发送端比接受端快)这个时候,接受端就会丢失信息,也不进行重发,导致数据报丢失
相关文章推荐
- 第8章 基本UDP套接口编程
- UNP Chapter 8 - 基本UDP套接口编程
- UNPv1第八章:基本UDP套接口编程
- UNIX网络编程读书笔记:基本UDP套接口编程
- 基本UDP套接口编程
- 基本UDP套接口编程
- 基本TCP套接口编程 (http://www.fanqiang.com)
- UNIX网络编程读书笔记:基本TCP套接口编程
- UDP套接口编程基础
- 第四章:基本TCP套接口编程
- 基本TCP套接口编程
- Unix网络编程 卷1 第8章: 基本UDP套接字编程(概述及recvfrom/sendto函数)
- 基本TCP套接口编程
- UNIX网络编程读书笔记:基本SCTP套接口编程
- UDP套接口编程
- 第8章:UDP套接口
- UNP Chapter 4 - 基本TCP套接口编程
- 第8章 可编程接口芯片及应用
- 基本的tcp套接口编程
- Unix网络编程卷1第4章 - 基本TCP套接口编程