红联Linux门户
Linux帮助

Linux下C语言实现简单的udp通信

发布时间:2017-03-20 10:06:35来源:linux网站作者:又双叒叕
用C语言实现UDP 通信。写一个udp 的客户端,可以向外发送消息。再写一个udp服务端,接收客户端的消息,并且打印出来。
 
事先说明:
在window和Linux中有一下结构:
struct sockaddr
{
unsigned short;
sa_family; //address family :AF_XXX
char sa_data[14]; // 14 bytes of the protocol address
}
struct sockaddr_in //在netinet/in.h 中定义:存储IP地址,使用in_addr这个数据结构
{
short sin_family; //address family:AF_XXX
unsigned short sin_port; //port number (必须采用网络数据格式,普通数字可以用htons()函数转换成网络数据格式的数字)
struct in_addr sin_addr; //ip address in nerwork byte order(internet address)
unsigned char sin_zero[8]; same size as struct sockaddr 没有实际意义,只是为了跟sockaddr结构在内存中对齐
}
typedef uint32_t, in_addr_t;
struct in_addr
{
in_addr_t;
s_addr;
}*
 
服务器代码如下:
#include <stdio.h>
#include <string.h>
#include <unistd.h> // for close()
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 12347  
#define MAXDATASIZE 1024  
int main()
{
int sockefd; // socket descriptors
struct sockaddr_in server; //server's address information
struct sockaddr_in client;  // client's address information
socklen_t sin_size;
int num, i;
char recemsg[MAXDATASIZE];
char sendmsg[MAXDATASIZE];
char condition[] = "quit";
/*create udp socket*/
if((sockefd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
printf("create socket failed\n");
exit(1);
}
bzero(&server, sizeof(server));//将字节类型的字符串的前n个字节为零,包括'\0'
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
server.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sockefd, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1)
{
printf("bind error!\n");
}
sin_size = sizeof(struct sockaddr_in);
while(1)
{
num = recvfrom(sockefd, recemsg, MAXDATASIZE, 0, (struct sockaddr *) &client, &sin_size);
if(num < 0)
{
printf("recvfrome error\n");
}
recemsg[num] = '\0';
printf("you got a message (%s) from %s\n", recemsg, inet_ntoa(client.sin_addr));
if(strcmp(recemsg, condition) == 0)
{
break;
}
for(i=0; i<num; i++)
{
sendmsg[i] = recemsg[num-1-i];
}
sendmsg[i] = '\0';
sendto(sockefd, sendmsg, strlen(sendmsg), 0 ,(struct sockaddr *)&client,sin_size);
}
close(sockefd);
return 0;
}
 
下面是客户端的代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define SERVER_IP "127.10.10.11"
#define PORT 12347
#define MAXDATASIZE 1024
int main()
{
int fd, numbytes;  //file discription
char recvbuff[MAXDATASIZE];
char sendbuff[MAXDATASIZE];
struct hostent *he;
struct sockaddr_in server, client;
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
printf("socket error!\n");
exit(1);
}
bzero(&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
server.sin_addr.s_addr = inet_addr(SERVER_IP);
socklen_t len;
len = sizeof(struct sockaddr_in);
while(1)
{
printf("please input the message! \n");
fgets(sendbuff, 40, stdin);
sendto(fd, sendbuff, strlen(sendbuff), 0, (struct sockaddr *)&server, len);
if((numbytes = recvfrom(fd, recvbuff, MAXDATASIZE, 0, (struct sockaddr *)&server,&len)) == -1)
{
printf("recvfrom is error! \n");
exit(1);
}
recvbuff[numbytes] = '\0';
printf("server return message is %s\n", recvbuff);
}
close(fd);
return 0;
}
 
这里客户端还有另一种写法,就是在启动客户端的代码时要手动传入IP的参数:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define SERVER_IP "127.10.10.11"
#define PORT 12347
#define MAXDATASIZE 1024
int main(int argc, char const *argv[])
{
int fd, numbytes;  //file discription
char recvbuff[MAXDATASIZE];
char sendbuff[MAXDATASIZE];
struct hostent *he;
struct sockaddr_in server, client;
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
printf("socket error!\n");
exit(1);
}
bzero(&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
server.sin_addr = *((struct in_addr *)he->h_addr);
socklen_t len;
len = sizeof(struct sockaddr_in);
while(1)
{
printf("please input the message! \n");
fgets(sendbuff, 40, stdin);
sendto(fd, sendbuff, strlen(sendbuff), 0, (struct sockaddr *)&server, len);
if((numbytes = recvfrom(fd, recvbuff, MAXDATASIZE, 0, (struct sockaddr *)&server,&len)) == -1)
{
printf("recvfrom is error! \n");
exit(1);
}
recvbuff[numbytes] = '\0';
printf("server return message is %s\n", recvbuff);
}
close(fd);
return 0;
}
 
编译:gcc client.c -oclient
运行:./client 127.0.0.1
此时的结果和上面的客户端代码的结果一样。
 
本文永久更新地址:http://www.linuxdiyf.com/linux/29317.html