目录
一、什么是UDP
二、UDP单播
本博客是使用UDP单播实现QQ聊天功能,更多有关UDP单播介绍和和实现,可以查看博主文章:
三、UDP实现QQ聊天功能
3.1 代码实现
由于是聊天,肯定需要两个程序收发数据来实现QQ聊天。
1. 第一个应用代码实现
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
/************************************************************************
函数名称: void *Recv_Thread(void* arg)
函数功能: 线程函数,负责接收对方的信息,并打印
函数参数: arg套接字
函数返回: 无
************************************************************************/
void *Recv_Thread(void* arg)
{
int sockfd = (int)arg;
struct sockaddr_in recvaddr;
socklen_t recvaddrlen = sizeof(recvaddr);
while(1)
{
char recv_buf[200] = "";
recvfrom(sockfd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr*)&recvaddr, &recvaddrlen);
printf("\r\033[31mUdpQQ1 Recv:%s\n",recv_buf);
printf("\r\033[32mUdpQQ1 Send:");
fflush(stdout);
}
return NULL;
}
/************************************************************************
函数名称: int main(int argc, char *argv[])
函数功能: 主函数,用线程实现聊天
函数参数: 无
函数返回: 无
************************************************************************/
int main(int argc, char *argv[])
{
struct sockaddr_in my_addr;
struct sockaddr_in dest_addr;
//对套接字地址进行初始化
bzero(&my_addr, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(8001);
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
bzero(&dest_addr, sizeof(dest_addr));
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(8000);
//创建套接口
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if( sockfd < 0)
{
perror("socket error");
exit(-1);
}
//设置端口
int err_log = bind(sockfd, (struct sockaddr*)&my_addr, sizeof(my_addr));
if( err_log < 0)
{
perror("bind");
close(sockfd);
exit(-1);
}
printf("Welcome ProYuan28 UDP QQ!!!\n");
//创建接收线程
pthread_t tid;
pthread_create(&tid, NULL, Recv_Thread, (void*)sockfd); //创建线程
//主进程负责发送消息
while(1)
{
printf("\r\033[32mUdpQQ1 Send:");
char send_buf[512] = "";
fgets(send_buf, sizeof(send_buf), stdin); //等待输入
send_buf[strlen(send_buf) - 1] = '\0'; //确保输入的最后一位是'\0'
if(strncmp(send_buf, "exit", 4) == 0)
{
close(sockfd);
exit(0);
}
sendto(sockfd, send_buf, strlen(send_buf), 0, (struct sockaddr*)&dest_addr, sizeof(dest_addr));
}
return 0;
}
2. 第二个应用
其他和上面一样,修改收发端口就行。
bzero(&my_addr, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(8000);
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
bzero(&dest_addr, sizeof(dest_addr));
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(8001);
3.2 编译
gcc qq_udp.c -o qq_udp -lpthread
3.3 效果
四、总结
一个简单QQ聊天就实现了,整个流程还是比较简单的,也是学习UDP通讯很经典的例子,更多Linux网络编程的学习,可以关注博主专栏,持续更新中,如有疑问,评论区留言或私信。
版权声明:本文为u012478275原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。