由于UDP不需要维护连接,程序逻辑简单了很多。
但是UDP协议是不可靠的,实际上有很
多保证通讯可靠性的机制需要在应用层实现。
服务端
接收来自客户端的字符串,将小写字母转为大写字符后发送给客户端
服务端源码server.c
/*server.c*/
#include
#include
#include
#include
#include
#include
#define MAXLINE 80
#define SERV_PORT 8000
int main()
{
struct sockaddr_in servaddr, cliaddr;
socklen_t cliaddr_len;
int sockfd;
char buf[MAXLINE];
char str[INET_ADDRSTRLEN];
int i, n;
/*打开一个网络通讯端口,分配一个文件描述符sockfd*/
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
bzero(&servaddr, sizeof(servaddr));//初始化为空
servaddr.sin_family = AF_INET;//地址采用IPv4地址
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);//地址从主机字节顺序转换成网络字节顺序
servaddr.sin_port = htons(SERV_PORT);//端口号从主机字节顺序转换成网络字节顺序
/*将文件描述符sockfd和服务器地址绑定*/
bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
printf("等待连接...\n");
while(1){
cliaddr_len = sizeof(cliaddr);
/*接收client端传过来的的字符串,写入buf*/
n = recvfrom(sockfd, buf, MAXLINE, 0, (struct sockaddr*)&cliaddr, &cliaddr_len);
if(n == -1){
printf("recvfrom error");
}
/*打印客户端IP及端口*/
printf("接收到来自地址为 %s 端口号为 %d 的数据\n",
(char*)inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),
ntohs(cliaddr.sin_port));
/*小写转为大写*/
for(i = 0; itoupper(buf[i]);
}
/*把数据发送给客户端*/
n = sendto(sockfd, buf, n, 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr));
if (n == -1){
printf("sendto error\n");
}
}
return 0;
}
客户端
客户端发送字符串给服务端,然后打印服务端传过来的数据
客户端源码client.c
/*client.c*/
#include
#include
#include
#include
#include
#include
#define MAXLINE 80
#define SERV_PORT 8000
int main(int argc, char *argv[])
{
struct sockaddr_in servaddr;
int sockfd, n;
char buf[MAXLINE];
char str[INET_ADDRSTRLEN];
socklen_t servaddr_len;
/*打开一个网络通讯端口,分配一个文件描述符sockfd*/
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_famliy = AF_INET;
inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr); //将“点分十进制” -> “二进制整数”
servaddr.sin_port = htons(SERV_PORT);//端口号从主机字节顺序转换成网络字节顺序
while(fgets(buf, MAXLINE, stdin) != NULL){ //输入字符串
/*发送给服务端*/
n = sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr*)&servaddr, sizeof(servaddr));
if(n == -1)
printf("sebdto err\n");
/*从服务端接收数据*/
n = recvfrom(sockfd, buf, MAXLINE, 0, NULL, 0);
if(n == -1)
printf("recvfrom err\n");
/*输出服务器处理后的数据*/
write(STDOUT_FILENO, buf, n);
}
close(sockfd);
return 0;
}
编译及执行结果如下:
yu@ubuntu:~/Linux/213$ ls
client.c server.c
yu@ubuntu:~/Linux/213$ gcc -o server server.c
yu@ubuntu:~/Linux/213$ gcc -o client client.c
yu@ubuntu:~/Linux/213$ ls
client client.c server server.c
yu@ubuntu:~/Linux/213$ ./server
等待连接...
接收到来自地址为 127.0.0.1 端口号为 40245 的数据
接收到来自地址为 127.0.0.1 端口号为 40245 的数据
接收到来自地址为 127.0.0.1 端口号为 40245 的数据
接收到来自地址为 127.0.0.1 端口号为 43352 的数据
^C
另开一端口,到当期目录打开客户端,执行./client
,发送三条信息后,发现服务端打印出三条相同信息。
CTRL+C
后再次打开./client
发送数据后发现服务端打印一条相同信息,端口号变了。
yu@ubuntu:~/Linux/213$ ./client
hey, how are you?
HEY, HOW ARE YOU?
give me your number ok?
GIVE ME YOUR NUMBER OK?
all right bye
ALL RIGHT BYE
^C
yu@ubuntu:~/Linux/213$ ./client
i do not believe love now
I DO NOT BELIEVE LOVE NOW
^C