#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#define ERR_MSG(msg) do{\
fprintf(stderr,"line:%d",__LINE__);\
perror(msg);\
}while(0)
int main(int argc, const char *argv[])
{
//创建报式套接字 来自 man 2 socket
int sfd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
//AF_INET表示IPv4
//SOCK_DGREAM表示报式套接字,用于UDP
//0表示指定协议 0表示默认 TCP:IPPROTO_TCP,UDP:IPPROTO_UDP;
if (sfd < 0)
{
ERR_MSG("socket");
return -1;
}
//填充服务器的IP和端口-->把IP和端口装进这个地址信息结构体里面
struct sockaddr_in sin; //定义一个地址信息结构体,存储IP和端口,来自man 7 ip
sin.sin_family = AF_INET; //表示IPv4
sin.sin_port = htons(8888); //用哪个端口,范围是1024~49151
sin.sin_addr.s_addr = inet_addr("192.168.249.132"); //服务器的IP
//绑定服务器自身的IP和端口到套接字上--->必须绑定
if (bind(sfd,(struct sockaddr *)&sin,sizeof(sin)) < 0) //"IP&端口"与"套接字"绑定
{
ERR_MSG("bind");
return -1;
}
printf("bind success\n");
//定义一个地址信息结构体,存储客户端发来数据的的“IP”和“端口”
struct sockaddr_in cin;
socklen_t addrlen = sizeof(cin); //cin地址信息结构体的大小
char buf[128] = "";
ssize_t res = 0;
while(1)
{
//接收数据
bzero(buf,sizeof(buf)); // 接收数据前先清空数组
res = recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr *)&cin,&addrlen); //接收数据包,并知道发送数据包的主机的IP和端口
if (res < 0)
{
ERR_MSG("recvfrom");
return -1;
}
printf("[%s:%d]:%s\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),buf); //所接收数据要由网络字节序转换为主机字节序
//发送数据:谁发给我,我就返回给谁。发送数据用sendto函数
//the size of the buffer in len-->sizeof(buf),而不是strlen(buf)
strcat(buf,"*_*");
if (sendto(sfd,buf,strlen(buf),0,(struct sockaddr *)&cin ,addrlen ) < 0)
{
ERR_MSG("sendto");
return -1;
}
printf("发送成功\n");
}
//关闭文件描述符
close(sfd);
return 0;
}
228



被折叠的 条评论
为什么被折叠?



