UDP是无连接的,在数据的发送之前不需要连接,只需要知道要发数据给谁,然后将数据发出即可,可以直接接收到其他人发来的数据,不必调用listen()和accept()函数。所以UDP中建立好套接字后,就可以直接进行数据的传输。
基于UDP的接收和发送函数:
#include
#include
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
函数说明:
sendto() 用来将数据由指定的socket 传给对方主机.
参数描述:
sockfd: 为已建好连线的socket, 如果利用UDP协议则不需经过连线操作
buf: 缓冲区
len:buf的大小
flags: 一般设0
dest_addr: 用来指定欲传送的网络地址, 结构sockaddr 请参考bind()
addrlen: 为sockaddr 的结构长度.
返回值:
成功则返回实际传送出去的字符数, 失败返回-1, 错误原因存于errno 中.
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
函数说明:
用来接收远程主机经指定的socket 传来的数据, 并把数据存到由参数buf 指向的内存空间
参数描述:
sockfd:为已建好连线的socket
buf:缓冲区
len:buf大小
flags:收取收取数据的方式
src_addr: 用来指定欲传送的网络地址, 结构sockaddr 请参考bind()
addrlen:为sockaddr 的结构长度
返回值:
成功则返回接收到的字符数,失败返回-1,错误原因存于errno 中.
server:
#include
#include
#include
#include
#include
#include
#include
static void usage(char* proc)
{
printf("Usage: %s [local_ip] [local_port]", proc);
}
int main(int argc, char* argv[])
{
if(argc != 3)
{
usage(argv[0]);
}
//创建套接字
int sock = socket(AF_INET, SOCK_DGRAM,0);
if(sock < 0)
{
perror("sock");
return 1;
}
struct sockaddr_in local;
local.sin_family = AF_INET;
local.sin_port = htons(atoi(argv[2]));
local.sin_addr.s_addr = inet_addr(argv[1]);
//将套接字描述符与IP和端口号进行绑定
if(bind(sock, (struct sockaddr*)&local, sizeof(local)) < 0 )
{
perror("bind");
return 2;
}
struct sockaddr_in client;
char buf[1024];
while(1)
{
socklen_t len = sizeof(client);
//接受客户端发来的信息,将客户端的套接字信息存储于client里
ssize_t s = recvfrom(sock, buf, sizeof(buf)-1, 0, (struct sockaddr*)&client, &len);
if(s > 0)
{
buf[s] = 0;
printf("client [%s] [%d]: %s", inet_ntoa(client.sin_addr), ntohs(client.sin_port),buf);
printf("Server : ");
fflush(stdout);
//从键盘读入信息
int _s = read(0, buf, sizeof(buf)-1);
buf[_s-1] = 0;
//发送信息到客户端
sendto(sock, buf, strlen(buf), 0, (struct sockaddr*)&client, sizeof(client));
}
else
{
perror("recvfrom");
return 3;
}
}
return 0;
}
client:
#include
#include
#include
#include
#include
#include
static void Usage(char *proc)
{
printf("Usage %s [server_ip] [server_port]\n", proc);
}
int main(int argc, char* argv[])
{
if(argc != 3)
{
Usage(argv[0]);
return 1;
}
//创建套接字, 注意使用udp套接字编程时应注意模式为SOCK_DGRAM
int sock = socket(AF_INET, SOCK_DGRAM,0);
if(sock < 0)
{
perror("socket");
return 2;
}
//获取服务器套接字信息
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[2]));
server.sin_addr.s_addr = inet_addr(argv[1]);
char buf[1024];
int len = sizeof(server);
//用peer接收发送给客户端的远程主机socket信息
struct sockaddr_in peer;
while(1)
{
printf("Please Enter# ");
fflush(stdout);
//从键盘写入内容到缓冲区
ssize_t s = read(0, buf, sizeof(buf)-1);
buf[s] = 0;
socklen_t len1 = sizeof(peer);
if(s >0)
{
printf("server# ");
//将缓冲区内容通过套接字发送到服务器
sendto(sock, buf, strlen(buf), 0, (struct sockaddr*)&server, sizeof(server));
//在从套接字中读取服务器的回应信息
ssize_t _s = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr*)&peer, &len1);
if(_s > 0)
{
buf[_s] = 0;
printf("%s\n", buf);
}
}
}
return 0;
}