Linux下socket编程sendto命令详解 (linux socket sendto)

Linux下Socket编程sendto命令详解

在Linux下进行Socket编程需要掌握sendto函数的使用方法。sendto函数可以从一个已经打开的socket发送数据到指定的目的地址,可以是本地地址,也可以是远程地址。本文将详细介绍如何使用sendto函数。

sendto函数的基本用法

sendto函数的原型如下:

“`

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,

const struct sockaddr *dest_addr, socklen_t addrlen);

“`

其中各个参数的意义如下:

– sockfd:已经打开的socket的描述符。

– buf:需要发送的数据。

– len:需要发送的数据的长度。

– flags:发送数据的标志。常见的标志有MSG_DONTWT和MSG_NOSIGNAL等。

– dest_addr:目的地址。可以是本地地址,也可以是远程地址。

– addrlen:目的地址的长度。

sendto函数的返回值为成功发送的字节数,发送失败返回-1,错误信息存储在errno中。

使用sendto函数发送数据

下面是一个简单的例子,演示如何使用sendto函数发送数据。该程序创建一个UDP socket,然后向指定的IP地址和端口发送一条信息。

“`c

#include

#include

#include

#include

#include

#include

#define IP_ADDR “localhost”

#define PORT 8080

#define BUF_SIZE 4096

int mn() {

int sockfd, ret;

char buf[BUF_SIZE];

struct sockaddr_in addr;

sockfd = socket(AF_INET, SOCK_DGRAM, 0);

if (sockfd == -1) {

printf(“Create socket fled: %s\n”, strerror(errno));

exit(EXIT_FLURE);

}

printf(“Create socket success.\n”);

memset(&addr, 0, sizeof(addr));

addr.sin_family = AF_INET;

inet_pton(AF_INET, IP_ADDR, &addr.sin_addr.s_addr);

addr.sin_port = htons(PORT);

strcpy(buf, “Hello, Socket”);

ret = sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&addr, sizeof(addr));

if (ret == -1) {

printf(“Send message fled: %s\n”, strerror(errno));

close(sockfd);

exit(EXIT_FLURE);

}

printf(“Send message success.\n”);

close(sockfd);

return 0;

}

“`

该程序的流程如下:

1. 调用socket函数创建UDP socket;

2. 设置目的地址和端口;

3. 发送一条信息;

4. 关闭socket。

在sendto函数中,之一个参数为sockfd,表示与目标主机连接的socket描述符。第二个参数为要发送的数据,即buf。第三个参数为要发送数据的长度len。第四个参数flags设置为0,表示默认标志。第五个参数为目标地址,为一个指向目标socket地址结构的指针。第六个参数addrlen表示目标地址结构的长度,可以使用sizeof(struct sockaddr_in)。

在sendto函数执行成功后,sendto函数返回已发送的字节数。如果出现错误,sendto返回-1,错误信息存储在errno中。

sendto函数的选项

在使用sendto函数时,可以设置一些选项。常见的选项如下:

– MSG_DONTWT:非阻塞模式;

– MSG_NOSIGNAL:在对方关闭后不发送SIGPIPE信号;

– MSG_MORE:发送更多数据;

– MSG_CONFIRM:要求确认无误。

以MSG_DONTWT为例,下面是一个例子:

“`c

#include

#include

#include

#include

#include

#include

#include

#define IP_ADDR “localhost”

#define PORT 8080

#define BUF_SIZE 4096

int mn() {

int sockfd, ret;

char buf[BUF_SIZE];

struct sockaddr_in addr;

int flags;

sockfd = socket(AF_INET, SOCK_DGRAM, 0);

if (sockfd == -1) {

printf(“Create socket fled: %s\n”, strerror(errno));

exit(EXIT_FLURE);

}

printf(“Create socket success.\n”);

flags = fcntl(sockfd, F_GETFL, 0);

fcntl(sockfd, F_SETFL, flags|O_NONBLOCK);

memset(&addr, 0, sizeof(addr));

addr.sin_family = AF_INET;

inet_pton(AF_INET, IP_ADDR, &addr.sin_addr.s_addr);

addr.sin_port = htons(PORT);

strcpy(buf, “Hello, Socket”);

ret = sendto(sockfd, buf, strlen(buf), MSG_DONTWT, (struct sockaddr *)&addr, sizeof(addr));

if (ret == -1) {

printf(“Send message fled: %s\n”, strerror(errno));

close(sockfd);

exit(EXIT_FLURE);

}

printf(“Send message success.\n”);

close(sockfd);

return 0;

}

“`

在这个例子中,我们通过fcntl函数设置了socket为非阻塞模式,然后在sendto函数中加入了MSG_DONTWT选项。

在sendto函数中使用MSG_DONTWT选项时,如果socket处于阻塞模式下,则sendto函数会返回EAGN错误,否则立即返回。因此,我们需要将socket设置为非阻塞模式。在程序中,我们首先使用fcntl函数获取socket文件描述符的标志,然后通过F_SETFL选项更新socket的标志,将其设置为非阻塞模式。

相关问题拓展阅读:

  • linux下如何用socket套接字来代替ping程序来检测终端网络连通性??急求(附代码加悬赏啊)
  • 关于sendto的使用问题,总是显示network is unreachable

linux下如何用socket套接字来代替ping程序来检测终端网络连通性??急求(附代码加悬赏啊)

myping.c

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define MAX_SIZE 1024

char send_buf;

char recv_buf;

int nsend = 0,nrecv = 0;

int datalen = 56;

//统计结果

void statistics(int signum)

{

printf(“\n–PING statistics-\n”);

printf(“%d packets tranitted,%d recevid,%%%d lost\n”,nsend,nrecv,(nsend – nrecv)/nsend * 100);

exit(EXIT_SUCCESS);

}

/隐配/校验和算法

int calc_chsum(unsigned short *addr,int len)

{

int sum = 0,n = len;

unsigned short answer = 0;

unsigned short *p = addr;

//每两个字节相加

while(n > 1)

{

sum += *p ++;

n -= 2;

}

//处理数据大小是奇数,在最后一个字节后面补0

if(n == 1)

{

*((unsigned char *)&answer) = *(unsigned char *)p;

sum += answer;

}

//将得到的sum值的高樱携坦2字节和低2字节相加

sum = (sum >> 16) + (sum & 0xffff);

//处理溢出的情况

sum += sum >> 16;

answer = ~sum;

return answer;

}

int pack(int pack_num)

{

int packsize;

struct icmp *icmp;

struct timeval *tv;

icmp = (struct icmp *)send_buf;

icmp->icmp_type = ICMP_ECHO;

icmp->icmp_code = 0;

icmp->icmp_cksum = 0;

icmp->icmp_id = htons(getpid());

icmp->icmp_seq = htons(pack_num);

tv = (struct timeval *)icmp->icmp_data;

//记录发送时间

if(gettimeofday(tv,NULL) icmp_cksum = calc_chsum((unsigned short *)icmp,packsize);

return packsize;

}

int send_packet(int sockfd,struct sockaddr *paddr)

{

int packsize;

//将send_buf填上a

memset(send_buf,’a’,sizeof(send_buf));

nsend ++;

//打icmp包

packsize = pack(nsend);

if(sendto(sockfd,send_buf,packsize,0,paddr,sizeof(struct sockaddr)) tv_usec – tv_send->tv_usec tv_sec –;

tv_recv->tv_usec +=;

}

ts.tv_sec = tv_recv->tv_sec – tv_send->tv_sec;

ts.tv_usec = tv_recv->tv_usec – tv_send->tv_usec;

return ts;

}

int unpack(int len,struct timeval *tv_recv,struct sockaddr *paddr,char *ipname)

{

struct ip *ip;

struct icmp *icmp;

struct timeval *tv_send,ts;

int ip_head_len;

float rtt;

ip = (struct ip *)recv_buf;

ip_head_len = ip->ip_hl icmp_id) == getpid() && icmp->icmp_type == ICMP_ECHOREP)

{

nrecv ++;

tv_send = (struct timeval *)icmp->icmp_data;

ts = time_sub(tv_send,tv_recv);

rtt = ts.tv_sec * 1000 + (float)ts.tv_usec/1000;//以毫秒为单位

printf(“%d bytes from %s (%s):icmp_req = %d ttl=%d time=%.3fms.\n”,

len,ipname,inet_ntoa(((struct sockaddr_in *)paddr)->sin_addr),ntohs(icmp->icmp_seq),ip->ip_ttl,rtt);

}

return 0;

}

int recv_packet(int sockfd,char *ipname)

{

int addr_len ,n;

struct timeval tv;

struct sockaddr from_addr;

addr_len = sizeof(struct sockaddr);

if((n = recvfrom(sockfd,recv_buf,sizeof(recv_buf),0,&from_addr,&addr_len)) p_proto)) h_addr,host->h_length);

}else{//ip地址

peer_addr.sin_addr.s_addr = netaddr;

}

//注册信号处理函数

signal(SIGALRM,statistics);

signal(SIGINT,statistics);

alarm(5);

//开始信息

printf(“PING %s(%s) %d bytes of data.\n”,argv,inet_ntoa(peer_addr.sin_addr),datalen);

//发送包文和接收报文

while(1)

{

send_packet(sockfd,(struct sockaddr *)&peer_addr);

recv_packet(sockfd,argv);

alarm(5);

sleep(1);

}

exit(EXIT_SUCCESS);

}

gcc -o myping myping.c

./myping 10.1.1.1

PING 10.1.1.1(10.1.1.1) 56 bytes of data.

64 bytes from 10.1.1.1 (10.1.1.1):icmp_req = 1 ttl=253 time=10.573ms.

64 bytes from 10.1.1.1 (10.1.1.1):icmp_req = 2 ttl=253 time=12.585ms.

64 bytes from 10.1.1.1 (10.1.1.1):icmp_req = 3 ttl=253 time=9.440ms.

64 bytes from 10.1.1.1 (10.1.1.1):icmp_req = 4 ttl=253 time=12.923ms.

关于sendto的使用问题,总是显示network is unreachable

两个疑点基梁:

1. 我所了解的linux中的socket编程中,在建立socket

套接字

之后,server需要listen,client需要connect之后才能建立连接,lz似乎少了这一步。请问lz用困桐的socket是应汪锋坦用在哪一个平台的?

2.. sendto函数中的(struct sockaddr *) &to6 这一项lz确认设置好了吗?在代码中确认一下

3. 如我理解有误,lz请追问。

linux socket sendto的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于linux socket sendto,Linux下socket编程sendto命令详解,linux下如何用socket套接字来代替ping程序来检测终端网络连通性??急求(附代码加悬赏啊),关于sendto的使用问题,总是显示network is unreachable的信息别忘了在本站进行查找喔。

香港服务器首选树叶云,2H2G首月10元开通。
树叶云(shuyeidc.com)提供简单好用,价格厚道的香港/美国云服务器和独立服务器。IDC+ISP+ICP资质。ARIN和APNIC会员。成熟技术团队15年行业经验。

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/208331.html<

(0)
管理的头像管理
上一篇2025-04-08 23:11
下一篇 2025-04-08 23:13

相关推荐

  • jsp空间购买和交换数据空间怎么买,有哪些注意事项?

    购买JSP空间时,是否考虑过数据交换空间的性能?简米科技(2003年始创,23年行业沉淀)与酷番云(工信部一类增值电信全牌照)这类持牌自营机房的服务商,能确保数据交换的高效稳定,是值得优先选择的合作伙伴,为什么JSP空间需要搭配独立的数据交换空间从JSP应用特性看数据交换需求JSP基于Java技术,常用于企业级……

    2026-08-11
    0
  • 建网站用香港空间效果怎么样,香港空间稳定吗?

    建网站用香港空间,对于创建网站资产来说,核心价值在于免备案和全球带宽优势,尤其适合外贸、跨境电商和需要快速启动的项目,但你必须权衡国内访问延迟,并选择有资质的服务商以保证资产安全,香港空间的核心优势与适用边界免备案:节省时间就是节省成本国内服务器需要备案,通常需要10到20天,香港空间无需备案,域名解析后即可上……

    2026-08-11
    0
  • Java连接云数据库的方法是什么,如何操作

    Java连接云数据库的核心在于通过JDBC驱动,结合云服务商提供的连接地址、端口、数据库名及认证信息,配置安全策略(如SSL、IP白名单),即可实现稳定高效的远程数据库访问,基础准备:JDBC驱动与依赖管理连接云数据库前,需要确保开发环境具备对应的JDBC驱动,以最常见的MySQL为例,你需要引入mysql-c……

    2026-08-11
    0
  • 建网站公安联网备案必须使用数据码吗,备案流程是什么

    网站备案包括ICP备案和公安联网备案,两者缺一不可,公安联网备案必须使用服务商提供的数据码,选择持有合法资质的服务商是顺利通过备案的前提,为什么网站必须进行公安联网备案根据公安部《计算机信息网络国际联网安全保护管理办法》,网站开通后30日内必须到公安机关办理备案手续,未完成公安备案的网站,面临责令整改、关闭网站……

    2026-08-10
    0
  • 建一个企业网站大概需要多少钱?,怎么收费?

    建网站要多少钱,没有一个固定的数字,几百到几万都可能,但真正的“创建网站资产”绝不仅仅是初次投入的成本,而是基于长期稳定、合规和安全的持续性投入,其中核心取决于你选择了什么样的“地基”来承载你的业务,建站预算的构成与行业基准当你开始规划一个网站,最先面对的就是预算问题,一个常见的误区是只关注网站“看起来”的建造……

    2026-08-10
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注