与TCP socket一致,基于UDP socket(无连接)编程分服务器端和客户端
服务器端过程:1.创建套接字(socket)2.将套接字绑定到一个本地地址和端口上(bind)3.用返回的套接字和客户端进行通信(recvfrom)4.返回,等待另一个客户请求。5.关闭套接字。
客户端过程:1.创建套接字(socket)2.和服务器端进行通信(sendto)3.关闭套接字
而与TCP不同的是:
(1)socket函数中type类型SOCK_DGRAM是一种无连接的Socket,对应于无连接的UDP服务应用
(2)使用了两种函数recvfrom和sendto
recvfrom函数::本函数用于从(已连接)套接口上接收数据,并捕获数据发送源的地址
sockfd:标识一个已连接套接口的描述字。
buf:接收数据缓冲区。
len:缓冲区长度。
flags:调用操作方式。
src_addr:(可选)指针,指向装有源地址的缓冲区。——输出型参数
addrlen:(可选)指针,指向from缓冲区长度值。——输入输出型参数。
返回值为整型,如果成功,则返回接收到的字节数,失败则返回SOCKET_ERROR。
sendto函数:指向一指定目的地发送数据,sendto()适用于发送未建立连接的UDP数据包
返回值为整型,如果成功,则返回发送的字节数,失败则返回SOCKET_ERROR。
sockfd: 套接字
buf: 待发送数据的缓冲区
len: 缓冲区长度
flags:调用方式标志位, 一般为0, 改变Flags,将会改变Sendto发送的形式:阻塞
addr:(可选)指针,指向目的套接字的地址
addr:lenaddr所指地址的长度
具体实现代码:
服务器端:
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
static void usage(const char* proc)
{
printf("%s [ip] [port]", proc);
}
int main(int argc,char* argv[])
{
if(argc != 3)
{
usage(argv[0]);
return 0;
}
int sock = socket(AF_INET, SOCK_DGRAM, 0);
if(sock < 0)
{
perror("socket");
return 2;
}
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]);
if(bind(sock, (struct sockaddr *)&local, sizeof(local)) < 0)
{
perror("bind");
return 3;
}
char buf[1024];
struct sockaddr_in client;
socklen_t len = sizeof(client);
while(1)
{
ssize_t s = recvfrom(sock, buf, sizeof(buf)-1, 0, (struct sockaddr*)&client, &len);
if(s > 0)
{
buf[s] = 0;
printf("%s : %d say# %s\n", inet_ntoa(client.sin_addr),ntohs(client.sin_port),buf);
ssize_t _s = sendto(sock, buf, sizeof(buf), 0, (struct sockaddr*)&client, len);
}
}
close(sock);
return 0;
}
客户端:
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
static void usage(const char* proc)
{
printf("%s [ip] [port]\n",proc);
}
int main(int argc, char* argv[])
{
if(argc != 3)
{
usage(argv[0]);
return 1;
}
int sock = socket(AF_INET, SOCK_DGRAM, 0);
if(sock < 0)
{
perror("socket");
return 2;
}
struct sockaddr_in peer;
peer.sin_family = AF_INET;
peer.sin_port = htons(atoi(argv[2]));
peer.sin_addr.s_addr = inet_addr(argv[1]);
char buf[1024];
while(1)
{
printf("Please Enter :");
fflush(stdout);
ssize_t s = read(0, buf, sizeof(buf)-1);
if(s > 0)
{
buf[s] = 0;
sendto(sock, buf, sizeof(buf), 0, (struct sockaddr*)&peer, sizeof(peer));
ssize_t _s = recvfrom(sock, buf, sizeof(buf)-1, 0, NULL, NULL);
printf("server echo# : %s\n", buf);
}
else if(s == 0)
{
printf("client quit...");
}
}
close(sock);
return 0;
}