服务器端:udp_ser.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <ctype.h>
#include <sys/socket.h>
#include <arpa/inet.h>
/*
udp:用户数据报协议,是一种无连接的传输层协议,提供面向事务的简单的不可靠信息的传送服务
tcp:传输控制协议,基于字节流的传输层通信协议。面向连接,可靠
udp服务端的C/S模型:
1)、socket() 创建套接字
2)、bind()
3)、listen() 设置监听上限
相比于TCP服务器,udp服务器有如下变化:
dup服务器中,没有监听套接字
1)、socket()函数中,第二个参数:SOCK_STREAM(流式)--》SOCK_DGRAM(报式)
2)、
listen()函数,严格意义上说,是用来指定客户端同时和服务器三次握手的数量,在UDP中没有三次捂手,可以不写。
同理,由于没有三次捂手,服务器端的accept()函数和客户端的connect()都不需要使用
在网络中,函数read()、write()只能用在TCP中,不能用在UDP中。在UDP中,可以使用函数recefrom()和sendto()。
函数recefrom()同时包含accept()的功能,传出(对端)的地址结构,sendto()同时也包含connect()的功能。
*/
#define SER_PORT 6781
void sys_err(const char *str)
{
perror(str);
exit(1);
}
int main (int argc,char *argv[])
{
int cfd;
int ret = 0,i;
char buf[1024]={0},cli_buf[1024]={0};
struct sockaddr_in ser_addr,cli_addr;
socklen_t cli_addr_len;
cfd = socket(AF_INET,SOCK_DGRAM,0);
if(cfd == -1) sys_err("socket fail \n");
/*地址结构*/
ser_addr.sin_family = AF_INET;
ser_addr.sin_port = htons(SER_PORT);
ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);
ret = bind(cfd,(struct sockaddr *)&ser_addr,sizeof(ser_addr));
if(ret == -1) sys_err("bind fail \n");
cli_addr_len = sizeof(cli_addr);
/*循环进行服务器的相关操作 */
while(1)
{
ret = recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr *)&cli_addr,&cli_addr_len);
/*打印客户端ip和端口号*/
printf("client ip=%s,端口号=%d \n",inet_ntop(AF_INET,&cli_addr.sin_addr.s_addr,cli_buf,sizeof(cli_buf)),
ntohs(cli_addr.sin_port));
/*对数据进行处理*/
for(i=0;i<ret;i++) buf[i] = toupper(buf[i]);
/*将转化以后的数据写回去*/
sendto(cfd,buf,ret,0,(struct sockaddr *)&cli_addr,cli_addr_len);
}
close(cfd);
return 0;
}
客户端:udp_cli.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <ctype.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define SER_PORT 6781
void sys_err(const char *str)
{
perror(str);
exit(1);
}
int main (int argc,char *argv[])
{
int cfd;
int ret = 0;
char buf[1024]={0};
struct sockaddr_in ser_addr,cli_addr;
cfd = socket(AF_INET,SOCK_DGRAM,0);
if(cfd == -1) sys_err("socket fail\n");
/*地址结构*/
ser_addr.sin_family = AF_INET;
ser_addr.sin_port = htons(SER_PORT);
inet_pton(AF_INET,"127.0.0.1",&ser_addr.sin_addr);
/*发送数据*/
while(1)
{
/*从标准输入得到数据,放入buf。此时,函数sendto()应该用strlen(buf),而不是sizeof(buf)*/
fgets(buf,sizeof(buf),stdin);
sendto(cfd,buf,strlen(buf),0,(struct sockaddr *)&ser_addr,sizeof(ser_addr));
/*为了效果更明显*/
sleep(1);
/*因为不需要服务器的地址结构了,所以用NULL*/
ret = recvfrom(cfd,buf,strlen(buf),0,NULL,0);
/*重定向,显示在屏幕*/
write(STDOUT_FILENO,buf,ret);
}
close(cfd);
return 0;
}