UDP和TCP的对比。
–UDP处理的细节比TCP少。
–UDP不能保证消息被传送到目的地。
–UDP不能保证数据包的传递顺序。
–TCP处理UDP不处理的细节。
–TCP是面向连接的协议。
–UDP是无连接协议。
–TCP保持一个连接。
–UDP只是把数据发送出去而已。
UDP和TCP在socket通信所用的代码基本类似
不同之处:
在创建套接字时属性type类型应为SOCK_DGRAM。如:int socket(int domain,int type,int protocol);
使用UDP时接收数据时,使用recvfrom函数。
使用UDP时发送数据时,使用sendto函数。
ssize_t sendto(int s,const void *buf,size_t len,int flags,const struct sockaddr * to,socklen_t tolen);
ssize_t recvfrom(int s,const void *buf,size_t len,int flags,const struct sockaddr * from,socklen_t fromlen);
实例:
client.c
UDP和TCP在socket通信所用的代码基本类似
不同之处:
在创建套接字时属性type类型应为SOCK_DGRAM。如:int socket(int domain,int type,int protocol);
使用UDP时接收数据时,使用recvfrom函数。
使用UDP时发送数据时,使用sendto函数。
ssize_t sendto(int s,const void *buf,size_t len,int flags,const struct sockaddr * to,socklen_t tolen);
ssize_t recvfrom(int s,const void *buf,size_t len,int flags,const struct sockaddr * from,socklen_t fromlen);
实例:
client.c
//使用UDP进行传输,并不会确保文件一定能够传送到,因为它是无连接协议的,TCP是面向连接协议的
//UDP客户端程序中的发送为sendto函数,接收为recvfrom函数,没有connect函数
//UDP服务端程序中,只需要bind,没有listen函数和accept
int main(void)
{
int st = socket(AF_INET,SOCK_DGRAM,0);//建立socket的时候第二个参数值为SOCK_DGRAM
if (st == -1)
{
printf("socket failed %s\n", strerror(errno));
return 0;
}
int on = 1;
if (setsockopt(st, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) == -1)//设置UDP socket可以发送广播消息
{
printf("setsockopt failed %s\n", strerror(errno));
return EXIT_FAILURE;
}
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(8080);
addr.sin_addr.s_addr = inet_addr("192.168.1.103");
char buf[1024];
while (1)
{
memset(buf, 0, sizeof(buf));
read(STDIN_FILENO, buf, sizeof(buf));//读取用户键盘输入
if (sendto(st, buf, strlen(buf), 0, (struct sockaddr *) &addr,sizeof(addr)) == -1)//udp使用sendto发送消息
{
printf("sendto failed %s\n", strerror(errno));
break;
}
}
close(st);
return EXIT_SUCCESS;
}
server.c
//服务端程序
int main()
{
int st = socket(AF_INET, SOCK_DGRAM, 0);
if (st == -1)
{
printf("socket failed %s\n", strerror(errno));
return 0;
}
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(8080);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(st, (struct sockaddr *)&addr, sizeof(addr)) == -1)//UDP接收数据,也需要绑定IP
{
printf("bind failed %s\n", strerror(errno));
return -1;
}
char buf[1024];
struct sockaddr_in client_addr;
socklen_t len = sizeof(client_addr);
while(1)
{
memset(&client_addr, 0, sizeof(client_addr));
memset(buf, 0, sizeof(buf));
if(recvfrom(st, buf, sizeof(buf), 0,(struct sockaddr *)&client_addr, &len) == -1)
{
printf("recvfrom failed %s\n", strerror(errno));
break;
}else
{
printf("%s recv is %s\n", inet_ntoa(client_addr.sin_addr), buf);
}
}
close(st);
return 0;
}