Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4533891
  • 博文数量: 252
  • 博客积分: 5347
  • 博客等级: 大校
  • 技术积分: 13838
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-30 10:13
文章分类
文章存档

2022年(12)

2017年(11)

2016年(7)

2015年(14)

2014年(20)

2012年(9)

2011年(20)

2010年(153)

2009年(6)

分类: LINUX

2011-04-02 13:50:52

从网上查到了一些关于这几个函数的使用及注意事项,现终结如下:
功能描述:
发送消息,send只可用于基于连接的套接字,send 和 write唯一的不同点是标志的存在,当标志为0时,send等同于write。sendto 和 sendmsg既可用于无连接的套接字,也可用于基于连接的套接字。除了套接字设置为非阻塞模式,调用将会阻塞直到数据被发送完。


用法:
#include <sys/types.h>
#include <sys/socket.h>

ssize_t send(int sock, const void *buf, size_t len, int flags);
ssize_t sendto(int sock, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen);
ssize_t sendmsg(int sock, const struct msghdr *msg, int flags);

参数: 

sock:索引将要从其发送数据的套接字。
buf:指向将要发送数据的缓冲区。
len:以上缓冲区的长度。
flags:是以下零个或者多个标志的组合体,可通过or操作连在一起

MSG_DONTROUTE:不要使用网关来发送封包,只发送到直接联网的主机。这个标志主要用于诊断或者路由程序。
MSG_DONTWAIT:操作不会被阻塞。
MSG_EOR:终止一个记录。
MSG_MORE:调用者有更多的数据需要发送。
MSG_NOSIGNAL:当另一端终止连接时,请求在基于流的错误套接字上不要发送SIGPIPE信号。
MSG_OOB:发送out-of-band数据(需要优先处理的数据),同时现行协议必须支持此种操作。

to:指向存放接收端地址的区域,可以为NULL。
tolen:以上内存区的长度,可以为0。
msg:指向存放发送消息头的内存缓冲,结构形态如下

struct msghdr {
    void         *msg_name;     



    socklen_t     msg_namelen;  
    struct iovec *msg_iov;      
    size_t        msg_iovlen;   
    void         *msg_control;  
    socklen_t     msg_controllen;
    int           msg_flags;    
};


可能用到的数据结构有

struct cmsghdr {
    socklen_t cmsg_len;   
    int       cmsg_level; 
    int       cmsg_type;  
  
};
返回说明: 
成功执行时,返回已发送的字节数。失败返回-1,errno被设为以下的某个值 
EACCES:对于Unix域套接字,不允许对目标套接字文件进行写,或者路径前驱的一个目录节点不可搜索
EAGAIN,EWOULDBLOCK: 套接字已标记为非阻塞,而发送操作被阻塞
EBADF:sock不是有效的描述词
ECONNRESET:连接被用户重置
EDESTADDRREQ:套接字不处于连接模式,没有指定对端地址
EFAULT:内存空间访问出错
EINTR:操作被信号中断
EINVAL:参数无效
EISCONN:基于连接的套接字已被连接上,同时指定接收对象
EMSGSIZE:消息太大
ENOMEM:内存不足
ENOTCONN:套接字尚未连接,目标没有给出
ENOTSOCK:sock索引的不是套接字
EPIPE:本地连接已关闭

#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
void Recv()
{
   struct sockaddr_in serv_addr;
   int sock_fd;
   char line[15] = "Hello world!";
   int size = 13;
   serv_addr.sin_family = AF_INET;
   serv_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
   serv_addr.sin_port = htons(5000);
   sock_fd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
   connect(sock_fd,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
   send(sock_fd, line, size, 0);
   close(sock_fd);
}


#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
void Sendto()
{
   sockaddr_in receiver_addr;
   int sock_fd;
   char line[15] = "Hello World!";
   sock_fd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
   receiver_addr.sin_family = AF_INET;
   receiver_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
   receiver_addr.sin_port = htons(5000);
   sendto(sock_fd, line, 13, 0,(struct sockaddr*)&receiver_addr,sizeof(receiver_addr));
   close(sock_fd);
}


#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
void sendmsg()
{
   struct sockaddr_in receiver_addr;
   int sock_fd;
   char line[15] = "Hello World!";
   struct msghdr msg;
   struct iovec iov;
   sock_fd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
 
   receiver_addr.sin_family = AF_INET;
   receiver_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
   receiver_addr.sin_port = htons(5000);
   msg.msg_name = &receiver_addr;
   msg.msg_namelen = sizeof(receiver_addr);
   msg.msg_iov = &iov;
   msg.msg_iovlen = 1;
   msg.msg_iov->iov_base = line;
   msg.msg_iov->iov_len = 13;
   msg.msg_control = 0;
   msg.msg_controllen = 0;
   msg.msg_flags = 0;
   sendmsg(sock_fd,&msg,0);
   close(sock_fd);
}


阅读(19280) | 评论(1) | 转发(4) |
给主人留下些什么吧!~~

chinaunix网友2011-06-02 17:18:32

招聘启示: 工作职责: 负责QQ后台服务器的开发 负责大容量网络服务后台架构开发 工作要求: 责任感强、有较强的逻辑思维能力、沟通能力、能够承担工作压力; 熟悉LINUX/UNIX开发环境,熟悉网络开发; 计算机或相关专业本科及以上学历,二年以上相关工作经验; 具有两年以上互联网业务开发经验或大容量网络服务相关经验者优先; 有后台业务开发、维护经验优先。 职位工作地:【深圳】 简历请发hcconquer@qq.com