UDP 的通信流程如下:
服务器端的实现udp_cs_server.c
:
#include
#include
#include
#include
#include
#include
#include
#include
void printPerror(const char *str)
{
printf("%s: %d: ", __FILE__, __LINE__);
perror(str);
}
int main()
{
// 建立套接字
int sfd = socket(AF_INET, SOCK_DGRAM, 0);
if(-1 == sfd) {
printPerror("socket");
exit(-1);
}
// 把套接字和本地主机信息进行绑定
struct sockaddr_in saddr;
bzero(&saddr, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(8888);
saddr.sin_addr.s_addr = INADDR_ANY;
if(bind(sfd, (struct sockaddr *)&saddr, sizeof(struct sockaddr)) == -1) {
printPerror("bind");
close(sfd);
exit(-1);
}
char buf[512] = {0};
while(1) {
// 接收来自客户端的消息
struct sockaddr_in fromaddr;
bzero(&fromaddr, sizeof(fromaddr));
int fromaddrlen = sizeof(struct sockaddr);
if(recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr *)&fromaddr, &fromaddrlen) == -1) {
printPerror("recvfrom");
close(sfd);
exit(-1);
}
printf("receive from %s %d, the message is: %s\n", inet_ntoa(fromaddr.sin_addr), ntohs(fromaddr.sin_port), buf);
// 发生消息
sendto(sfd, "world", 6, 0, (struct sockaddr *)&fromaddr, sizeof(struct sockaddr));
}
close(sfd);
}
客户端的实现udp_cs_client.c
:
#include
#include
#include
#include
#include
#include
#include
#include
void printPerror(const char *str)
{
printf("%s: %d: ", __FILE__, __LINE__);
perror(str);
}
int main(int argc, char *argv[])
{
// 建立套接字
int sfd = socket(AF_INET, SOCK_DGRAM, 0);
if(-1 == sfd) {
printPerror("socket");
exit(-1);
}
// 发生消息
struct sockaddr_in toaddr;
bzero(&toaddr, sizeof(toaddr));
toaddr.sin_family = AF_INET;
toaddr.sin_port = htons(8888);
toaddr.sin_addr.s_addr = inet_addr(argv[1]); // 此处为服务器的ip
sendto(sfd, "hello", 6, 0, (struct sockaddr *)&toaddr, sizeof(struct sockaddr));
// 接收消息
char buf[512] = {0};
struct sockaddr_in fromaddr;
bzero(&fromaddr, sizeof(fromaddr));
int fromaddrlen = sizeof(struct sockaddr);
if(recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr *)&fromaddr, &fromaddrlen) == -1) {
printPerror("recvfrom");
close(sfd);
exit(-1);
}
printf("receive from %s %d, the message is: %s\n", inet_ntoa(fromaddr.sin_addr), ntohs(fromaddr.sin_port), buf);
close(sfd);
}
UDP 发生文件时,先发送文件的大小,再发送文件的内容。
服务器端代码的实现:udp_cs_server_file.c
:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
void printPerror(const char *str)
{
printf("%s: %d: ", __FILE__, __LINE__);
perror(str);
}
int main()
{
int sfd = socket(AF_INET, SOCK_DGRAM, 0);
if(-1 == sfd) {
printPerror("socket");
exit(-1);
}
struct sockaddr_in saddr;
bzero(&saddr, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(8888);
saddr.sin_addr.s_addr = INADDR_ANY;
if(bind(sfd, (struct sockaddr *)&saddr, sizeof(struct sockaddr)) == -1) {
printPerror("bind");
close(sfd);
exit(-1);
}
char buf[512] = {0};
struct sockaddr_in fromaddr;
bzero(&fromaddr, sizeof(fromaddr));
int fromaddrlen = sizeof(struct sockaddr);
if(recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr *)&fromaddr, &fromaddrlen) == -1) {
printPerror("recvfrom");
close(sfd);
exit(-1);
}
printf("receive from %s %d, the message is: %s\n", inet_ntoa(fromaddr.sin_addr), ntohs(fromaddr.sin_port), buf);
FILE *fp = fopen("1.txt", "rb");
struct stat st; // 获取文件大小
stat("1.txt", &st);
int filelen = st.st_size;
sendto(sfd, (void*)&filelen, sizeof(int), 0, (struct sockaddr *)&fromaddr, sizeof(struct sockaddr));
// 发送文件数据
while(!feof(fp)) {
int len = fread(buf, 1, sizeof(buf), fp);
sendto(sfd, buf, len, 0, (struct sockaddr *)&fromaddr, sizeof(struct sockaddr));
}
close(sfd);
}
创建客户端代码udp_cs_client_file.c
:
#include
#include
#include
#include
#include
#include
#include
#include
#define BUFSIZE 512
void printPerror(const char *str)
{
printf("%s: %d: ", __FILE__, __LINE__);
perror(str);
}
int main(int argc, char *argv[])
{
int sfd = socket(AF_INET, SOCK_DGRAM, 0);
if(-1 == sfd) {
printPerror("socket");
exit(-1);
}
struct sockaddr_in toaddr;
bzero(&toaddr, sizeof(toaddr));
toaddr.sin_family = AF_INET;
toaddr.sin_port = htons(8888);
toaddr.sin_addr.s_addr = inet_addr(argv[1]); // 此处为服务器的ip
sendto(sfd, "hello", 6, 0, (struct sockaddr *)&toaddr, sizeof(struct sockaddr));
char buf[BUFSIZE] = {0};
struct sockaddr_in fromaddr;
bzero(&fromaddr, sizeof(fromaddr));
int fromaddrlen = sizeof(struct sockaddr);
int filelen = 0; // 用于保存文件的长度
FILE *fp = fopen("2.txt", "w+b");
recvfrom(sfd, (void *)&filelen, sizeof(int), 0, (struct sockaddr *)&fromaddr, &fromaddrlen);
printf("the length of file is %d\n", filelen);
printf("Create a new file!\n");
printf("begin to receive file content!\n");
// 接收此文件
while(1) {
int len = recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr *)&fromaddr, &fromaddrlen);
if(len < BUFSIZE) {
// 如果接收的长度小于BUFFSIZE,则表示最后一次接收
fwrite(buf, sizeof(char), len, fp);
break;
}
fwrite(buf, sizeof(char), len, fp);
}
printf("receive file finished!\n");
close(sfd);
}