UDP编程-创建套接字(1)

1.创建套接字

#include <sys/socket.h>
int socket(int family, int type, int protocol);
/*
功能:
	创建一个用于网络通信的socket套接字(描述符)
参数:
	family:协议族(AF_INET、AF_INET6、PF_PACKET等)
	type:套接字类(SOCK_STREAM、SOCK_DGRAM、SOCK_RAW等)
	protocol:协议类别(0、IPPROATO_TCP、IPPROTO_UDP等)
返回值:
	套接字
特点:
	创建套接字时,系统不会分配端口
	创建的套接字默认属性是主动的,及主动发起服务的请求;当作为服务器时,往往需要修改为被动的。
*/

//创建套接字demo
int sockfd=0;
sockfd=socket(AF_INET, SOCK_DGRAM,0);
if(sockfd<0)
{
	perror("socket");
	exit(-1);
}
/*
AF_INET: IPV4协议
SOCK_DGRAM:数据包套接字
0:选择所给定的family和type组合的系统默认值
*/

2.UDP编程-发送、绑定、接受数据

2.1 IPV4套接字地址结构

#include <netinet/in.h>
struct in_addr
{
	in-addr_t s_addr;//4字节
};

stuct sockaddr_in
{
	sa_family_t sin_family;//2字节
	in_port sin_port;//2字节
	struct in_addr_sin_addr;//4字节
	char sin_zero[8];//8字节
};

//为了使不同格式地址能被传入套接字函数,地址必须要强制转换成通用套接字地址结构

#include <netinet/in.h>
struct sockaddr
{
	sa_family_t sa_family;//2字节
	char sa_data[14];//14字节
}
在定义源地址和目的地址结构的时候,选用struct sockaddr_in

例:
struct sockaddr_in my_addr;
当调用编程接口函数,且函数需要传入地址结构时需要用struct sockaddr进行强制转换
例:
bind(sockfd, (struct sockaddr*)&my_addr, sizeof(my_addr));

2.2 发送数据----sendto函数浅析

ssize_t sendto(int sockfd, const void *buf,
				size_t nbytes,int flags,
				const struct sockaddr *to,
				socklen_t addrlen);
/*
功能:
	向to结构体指针中指定的ip,发送UDP数据
参数:
	sockfd:套接字
	buf:  发送数据缓冲区
	nbytes:发送数据缓冲区的大小
	flags:一般为0
	to:指向目的主机地址结构体的指针
	addrlen:to所指向内容的长度
注意:
	通过to和addrlen确定目的地址
	可以发送0长度的UDP数据包
返回值:
	成功:发送数据的字符数
	失败:-1
*/

2.3 通过网络调试助手发送消息

通过Ubuntu终端向调试助手发送信息
在这里插入图片描述
在这里插入图片描述
参考例程

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(int argc, char *argv[])
{
	unsigned short port=8088;
	char *server_ip ="填写你自己电脑的IP地址";
	
	if (argc>1)//通过main函数传参,传入ip地址
	{
		server_ip=argv[1];
	}

	if (argc>2)//通过main函数传参 传入端口号
	{
		port=atoi(argv[2]);
	}

	//创建UDP套接字

	int sockfd;
	sockfd=socket(AF_INET, SOCK_DGRAM, 0);

	if(sockfd<0)
	{
		perror("socket");
		exit(-1);
	}


	//填充目的server socket地址

	struct sockaddr_in dest_addr;
	
	bzero(&dest_addr, sizeof(dest_addr));

	dest_addr.sin_family=AF_INET;//目的套接字地址的协议家族赋值

	dest_addr.sin_port=htons(port);//目的套接字地址的端口号赋值

	inet_pton(AF_INET, server_ip, &dest_addr.sin_addr);//目的套接字地址的ip地址赋值

	printf("发送数据到UDP服务器 %s:%d!\n", server_ip,port);

	//发送数据到目的server
	while(1)
	{
		char send_buf[512];
		fgets(send_buf, sizeof(send_buf), stdin);

		send_buf[strlen(send_buf)-1]='\0';//字符串最后一个'\n'变成'\0'

		sendto(sockfd, send_buf,strlen(send_buf), 0, (struct sockaddr*)&dest_addr, sizeof(dest_addr));

	}

	close(sockfd);



	return 0;
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小蜗牛爱代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值