您的位置:首页 > 运维架构 > Linux

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

2016-04-28 10:13 501 查看
用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

此时的结果和上面的客户端代码的结果一样。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: