您的位置:首页 > 理论基础 > 计算机网络

网络编程UDP的socket编程实现(linux下)

2013-06-10 14:29 417 查看

网络编程UDP的socket编程实现(linux下)

一、UDP的编程步骤:

1、服务器端:

socket()->bind()->recvfrom()->sendto()->close()

2、客户端:

socket()->sendto()->recvfrom()->close()

二、主要的API

1、sendto()函数的使用

#include <sys/types.h>

#include <sys/socket.h>

ssize_t sendto(int sockfd, const void * buf, size_t len , int flags, const struct sockaddr * dest_addr , socklen_t addrlen);

(1)功能:向指定的数据接收端发送指定的数据。

(2)返回值:成功,返回实际发送的字节数。失败,返回-1.

(3)参数:

----sockfd:发送操作使用的套接字文件描述符

-----buf:要发送的数据在内存中的首地址

-----len:要发送的数据的长度

------flags:发送标志,一般为0

------dest_addr:数据接收端的地址(包含IP地址和端口号)的结构体指针

-------addrlen:数据接收端地址结构体的大小

2、recvfrom()函数的使用

#include <sys/types.h>

#include <sys/socket.h>

ssize_t recvfrom(int sockfd, void * buf , size_t len , int flags , struct sockaddr * src_addr, socklen_t * addrlen);

(1)功能:接收数据发送端到达的数据

(2)返回值:成功,返回实际接收到的字节数。失败返回-1

(3)参数:

-----sockfd:接收操作使用的套接字文件描述符

-----buf:接收到的数据存放在内存中的位置

------len:指buf缓冲区的大小,即期望接收的最大数据的长度

-----flags:接收标志,一般为0

-----src_addr:指向的结构体将被数据发送端的地址(含IP地址和端口号)所填充

-----addrlen:所指向的存储位置,调用前应填入src_addr和addrlen的结构体大小,调用后则将被填入发送端的地址的实际大小

备注:若不需要发送端的IP地址和端口号,可以将src_addr和addrlen都设置为NULL

三、示例:

服务器端代码:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <error.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>

#define SERVER_PORT 8888
#define MAX_MSG_SIZE 1024

void udps_respon(int sockfd)
{
struct sockaddr_in addr;
int n,i;
unsigned int addrlen;
char msg[MAX_MSG_SIZE];
while(1)
{
n = recvfrom(sockfd,msg,MAX_MSG_SIZE,0,(struct sockaddr *)&addr,&addrlen);
msg
=0;
fprintf(stdout,"I have received %s",msg);
n=strlen(msg);
for(i=0;i<n;i++)
{
msg[i] = toupper(msg[i]);
}
sendto(sockfd,msg,n,0,(struct sockaddr *)&addr,addrlen);
}
}

int main()
{
int sockfd;
struct sockaddr_in addr;
sockfd = socket(AF_INET,SOCK_DGRAM,0);
bzero(&addr,sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(SERVER_PORT);
if( bind(sockfd,(struct sockaddr *)&addr,sizeof(struct sockaddr_in) )<0 )
{
perror("bind");
exit(1);
}
udps_respon(sockfd);
close(sockfd);
return 0;
}



客户端代码:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>

#define MAX_BUF_SIZE 1024

void udpc_requ(int sockfd,const struct sockaddr_in * addr,int len)
{//
char buffer[MAX_BUF_SIZE];
int n;
while(1)
{
fgets(buffer,MAX_BUF_SIZE,stdin);
sendto(sockfd,buffer,strlen(buffer),0,(struct sockaddr *)addr,len);
printf("I have sent to server %s",buffer);
printf("Waiting respond from server\n");
bzero(buffer,MAX_BUF_SIZE);
n=recvfrom(sockfd,buffer,MAX_BUF_SIZE,0,NULL,NULL);
buffer
=0;
printf("I have received from server..");
fputs(buffer,stdout);
printf("\n");
}
}

int main(int argc,char ** argv)
{
int sockfd,port;
struct sockaddr_in addr;
if(argc != 3 )
{
fprintf(stderr,"Usage:%s server_ip server_port\n",argv[0]);
exit(1);
}
if((port = atoi(argv[2]) )< 0)
{
fprintf(stderr,"Usage:%s server_ip server_port\n",argv[0]);
exit(1);
}

sockfd = socket(AF_INET,SOCK_DGRAM,0);
bzero(&addr,sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
if(inet_aton(argv[1],&addr.sin_addr) < 0)
{
fprintf(stderr,"IP error:%s\n",strerror(errno));
exit(1);
}

udpc_requ(sockfd,&addr,sizeof(struct sockaddr_in));
close(sockfd);
return 0;

}

运行结果:

服务器端:

[root@rac2 ~]# ./udpServer
I have received abc
I have received zhandan

客户端:

[root@rac2 ~]# ./udpClient 127.0.0.1 8888
abc
I have sent to server abc
Waiting respond from server
I have received from server..ABC

zhandan
I have sent to server zhandan
Waiting respond from server
I have received from server..ZHANDAN
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: