udp_client.c
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#define SERVER_IP "172.17.15.227" //服务器IP
#define SERVER_PORT 60000
#define OTHER_IP "192.168.11.91" //其他人的IP
#define OTHER_PORT 60001
struct send_info
{
char buf[1024];
struct sockaddr_in other_addr; //其它人的地址
};
//接收其他人发来的消息
void *recv_buf(void *arg)
{
pthread_detach(pthread_self());
int socket_fd = *(int *)arg;
int ret;
struct sockaddr_in recv_addr;
socklen_t address_len = sizeof(recv_addr);
while(1)
{
struct send_info recv_info;
memset(&recv_info,0,sizeof(recv_info));
ret = recvfrom(socket_fd,&recv_info,sizeof(recv_info),0,(struct sockaddr *)&recv_addr,&address_len);
//打印接受的客户端的信息
char *ip = inet_ntoa(recv_addr.sin_addr);
int port = ntohs(recv_addr.sin_port);
//printf("接收到的信息[ip:%s port:%d]buf:%s ret:%d\n",ip,port,recv_info.buf,ret);
printf("接收到的信息buf:%s ret:%d\n",recv_info.buf,ret);
}
}
int main(int argc,char **argv)
{
if(argc != 3)
{
printf("请输入发送给他人的IP地址和端口<ip><port>\n");//键盘输入你要发送的ip和端口号
return -1;
}
int ret;
//创建套接字
int socket_fd;
//ipv4:AF_INET UDP协议:SOCK_DGRAM
socket_fd = socket(AF_INET,SOCK_DGRAM,0);
if(socket_fd < 0)
{
perror("socket fail");
return -1;
}
pthread_t tid;
ret = pthread_create(&tid,NULL,recv_buf,&socket_fd);
if(ret != 0)
{
perror("pthread_create fail");
return -1;
}
//填充服务器的IP地址
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;//地址族
server_addr.sin_port = htons(SERVER_PORT);//将本机端口转换为网络端口
server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);//将本机IP转换为网络IP
//socklen_t dest_len = sizeof(server_addr);
//直接给UDP的服务器发送数据
while(1)
{
//printf("请输入发送的信息:");
struct send_info info;
scanf("%s",info.buf);//输入的信息
info.other_addr.sin_family = AF_INET;
// info.other_addr.sin_port = htons(OTHER_PORT);//其他人的端口
// info.other_addr.sin_addr.s_addr = inet_addr(OTHER_IP);//其他人的IP
info.other_addr.sin_port = htons(atoi(argv[2]));//键盘输入端口
info.other_addr.sin_addr.s_addr = inet_addr(argv[1]);//键盘输入IP
//给服务器发送数据
ret = sendto(socket_fd,&info,sizeof(struct send_info),0,(struct sockaddr *)&server_addr,sizeof(server_addr));
printf("send success ret:%d\n",ret);
}
//关闭套接字
close(socket_fd);
return 0;
}
udp_server.c
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define SERVER_IP "172.17.15.227" //服务器IP
#define SERVER_PORT 60000
#define OTHER_IP "172.17.15.227"
#define OTHER_PORT 60008
struct send_info
{
char buf[1024];
struct sockaddr_in other_addr; //其它人的地址
};
int main(int argc,char **argv)
{
int ret;
int socket_fd;
//udp协议:SOCK_DGRAM
socket_fd = socket(AF_INET,SOCK_DGRAM,0);
if(socket_fd < 0)
{
perror("socket fail");
return -1;
}
//填充服务器的IP地址
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;//地址族
server_addr.sin_port = htons(SERVER_PORT);//将本机端口转换为网络端口
server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);//将本机IP转换为网络IP
socklen_t addrlen = sizeof(server_addr);
//绑定本机IP
ret = bind(socket_fd,(struct sockaddr *)&server_addr,addrlen);
if(ret < 0)
{
perror("bind fail");
return -1;
}
printf("bind success\n");
//新建一个用来接受客户端的地址
struct sockaddr_in client_addr;
socklen_t address_len = sizeof(client_addr);
char *ip = NULL;
int port = 0;
struct send_info recv_info;
while(1)
{
//接收客户端数据
memset(&recv_info,0,sizeof(recv_info));
ret = recvfrom(socket_fd,&recv_info,sizeof(recv_info),0,(struct sockaddr *)&client_addr,&address_len);
if(ret < 0)
{
perror("client down");
return -1;
}
//打印接受的客户端的信息
ip = inet_ntoa(client_addr.sin_addr);
port = ntohs(client_addr.sin_port);
printf("[ip:%s port:%d]buf:%s ret:%d\n",ip,port,recv_info.buf,ret);
//解析recv_info里面的其他人的地址和端口
ip = inet_ntoa(recv_info.other_addr.sin_addr);
port = ntohs(recv_info.other_addr.sin_port);
if( port == 0)
{
recv_info.other_addr.sin_port = htons(OTHER_PORT);//将本机端口转换为网络端口
recv_info.other_addr.sin_addr.s_addr = inet_addr(OTHER_IP);//将本机IP转换为网络IP
ip = inet_ntoa(recv_info.other_addr.sin_addr);
port = ntohs(recv_info.other_addr.sin_port);
printf("[other_addr ip:%s port:%d buf:%s]\n",ip,port,recv_info.buf);
printf("-------------------------------------------------------\n");
struct sockaddr_in recv_addr = recv_info.other_addr; //其他人的地址
//将客户端的的数据转发给其他人的地址和端口号
sendto(socket_fd,recv_info.buf,strlen(recv_info.buf),0,(struct sockaddr *)&recv_addr,sizeof(recv_addr));
}
else
{
printf("[other_addr ip:%s port:%d buf:%s]\n",ip,port,recv_info.buf);
printf("-------------------------------------------------------\n");
struct sockaddr_in recv_addr = recv_info.other_addr; //其他人的地址
//将客户端的的数据转发给其他人的地址和端口号
sendto(socket_fd,recv_info.buf,strlen(recv_info.buf),0,(struct sockaddr *)&recv_addr,sizeof(recv_addr));
}
}
//关闭套接字
close(socket_fd);
return 0;
}
gcc.sh
#!/bin/bash
gcc 1_udp_client_转发.c -o client -lpthread
arm-linux-gcc 1_udp_client_转发.c -o client_arm -lpthread
gcc 2_udp_server_转发.c -o server