1.广播
发送端
#include <myhead.h>
#define ERR_MSG(msg) do{\
fprintf(stderr, "__%d__\n", __LINE__);\
perror("msg");\
}while(0)
#define IP "192.168.123.255"
#define PORT 8888
int main(int argc, const char *argv[])
{
//创建套接字
int sfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sfd < 0)
{
ERR_MSG("socket");
return -1;
}
//设置允许广播
int broad = 1;
if (setsockopt(sfd, SOL_SOCKET, SO_BROADCAST, (void *)&broad, sizeof(broad)) < 0)
{
ERR_MSG("setsockopt");
return -1;
}
//存储接收方信息
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr(IP);
sin.sin_port = htons(PORT);
char buf[128] = "";
//发送信息
while(1)
{
bzero(buf, sizeof(buf));
fgets(buf, sizeof(buf), stdin);
buf[strlen(buf) - 1] = '\0';
if (sendto(sfd, buf, sizeof(buf), 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
{
ERR_MSG("sendto");
return -1;
}
}
close(sfd);
return 0;
}
接收端
#include <myhead.h>
#define ERR_MSG(msg) do{\
fprintf(stderr, "__%d__\n", __LINE__);\
perror("msg");\
}while(0)
#define IP "192.168.123.255"
#define PORT 8888
int main(int argc, const char *argv[])
{
//创建套接字
int sfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sfd < 0)
{
ERR_MSG("socket");
return -1;
}
//绑定发送方信息
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(IP);
if (bind(sfd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
{
ERR_MSG("bind");
return -1;
}
char buf[128] = "";
//接收信息
while(1)
{
bzero(buf, sizeof(buf));
if (recvfrom(sfd, buf, sizeof(buf), 0, NULL, NULL) < 0)
{
ERR_MSG("sendto");
return -1;
}
printf(": %s\n", buf);
}
close(sfd);
return 0;
}
2.组播
2.1发送端
#include <myhead.h>
#define ERR_MSG(msg) do{\
fprintf(stderr, "__%d__\n", __LINE__);\
perror("msg");\
}while(0)
#define IP "224.10.2.3"
#define PORT 6666
int main(int argc, const char *argv[])
{
//创建套接字
int sfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sfd < 0)
{
ERR_MSG("socket");
return -1;
}
//存储接收方信息
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(IP);
char buf[128] = "";
while(1)
{
bzero(buf,sizeof(buf));
fgets(buf, sizeof(buf), stdin);
buf[strlen(buf) - 1] = '\0';
//发送信息
if (sendto(sfd, buf, sizeof(buf), 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
{
ERR_MSG("sendto");
return -1;
}
printf("发送成功\n");
}
close(sfd);
return 0;
}
2.2接收端
#include <myhead.h>
#define ERR_MSG(msg) do{\
fprintf(stderr, "__%d__\n", __LINE__);\
perror("msg");\
}while(0)
#define zb_IP "224.1.2.3"
#define loc_IP "192.168.122.221"
#define PORT 8888
int main(int argc, const char *argv[])
{
//创建套接字
int sfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sfd < 0)
{
ERR_MSG("socket");
return -1;
}
//设置组播
struct ip_mreqn mq;
mq.imr_multiaddr.s_addr = inet_addr(zb_IP);
mq.imr_address.s_addr = inet_addr(loc_IP);
mq.imr_ifindex = 2;
if (setsockopt(sfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mq, sizeof(mq)) < 0)
{
ERR_MSG("setsockopt");
return -1;
}
//存储发送方信息
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(loc_IP);
char buf[128] = "";
while(1)
{
//接收信息
if (recvfrom(sfd, buf, sizeof(buf), 0, NULL, NULL) < 0)
{
ERR_MSG("recvfrom");
return -1;
}
}
close(sfd);
return 0;
}
3.多进程模型
#include <myhead.h>
#define ERR_MSG(msg) do{\
fprintf(stderr, "__%d__\n", __LINE__);\
perror("msg");\
}while(0)
#define IP "192.168.122.221"
#define PORT 6666
int deal_cli_msg(int newfd, struct sockaddr_in cin);
void handler(int sig)
{
while(waitpid(-1, NULL, WNOHANG) > 0);
}
int main(int argc, const char *argv[])
{
//绑定17号信号
if (signal(SIGCHLD, handler) == SIG_ERR)
{
ERR_MSG("signal");
return -1;
}
//获取套接字
int sfd = socket(AF_INET, SOCK_STREAM, 0);
if (sfd < 0)
{
ERR_MSG("socket");
return -1;
}
printf("socket success\n");
//设置端口快速重用
int rouse = 1;
if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &rouse, sizeof(rouse)) < 0)
{
ERR_MSG("setsockopt");
return -1;
}
printf("setpost success\n");
//绑定服务器信息
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(IP);
if (bind(sfd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
{
ERR_MSG("bind");
return -1;
}
printf("bind success\n");
//设置被动监听
if (listen(sfd, 128) < 0)
{
ERR_MSG("listen");
return -1;
}
printf("listen success\n");
//存储发送方信息
struct sockaddr_in cin;
socklen_t address = sizeof(cin);
pid_t pid = 0;
int newfd = -1;
while(1)
{
//等待客户端连接
newfd = accept(sfd, (struct sockaddr *)&cin, &address);
if (newfd < 0)
{
ERR_MSG("accept");
return -1;
}
printf("accept success\n");
//创建子进程用于接发信息
pid = fork();
if (0 == pid)
{
close(sfd);
deal_cli_msg(newfd,cin);
close(newfd);
exit(0);
}
close(newfd);
waitpid(-1, NULL, WNOHANG);
}
close(sfd);
return 0;
}
int deal_cli_msg(int newfd, struct sockaddr_in cin)
{
ssize_t res = 0;
char buf[128] = "";
while (1)
{
bzero(buf, sizeof(buf));
//接收信息
res = recv(newfd, buf, sizeof(buf), 0);
if (res < 0)
{
ERR_MSG("recv");
return -1;
}
else if (res == 0)
{
printf("[%s : %d] :offline\n",\
inet_ntoa(cin.sin_addr), ntohs(cin.sin_port));
break;
}
else
printf("[%s : %d] : %s\n",\
inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), buf);
strcat(buf,"*_*");
//发送信息
if (send(newfd, buf, sizeof(buf), 0) < 0)
{
ERR_MSG("send");
return -1;
}
printf("send success\n");
}
return 0;
}
4.上传下载
#include <myhead.h>
#define ERR_MSG(msg) do{\
fprintf(stderr, "line:%d\n", __LINE__);\
perror(msg);\
}while(0)
#define IP "192.168.122.111"
#define PORT 69
int do_download(int cfd,struct sockaddr_in sin);
int do_upload(int cfd, struct sockaddr_in sin);
int main(int argc, const char *argv[])
{
//创建报式套接字
int cfd = socket(AF_INET, SOCK_DGRAM, 0);
if (cfd < 0)
{
ERR_MSG("socket");
return -1;
}
printf("cfd = %d\n", cfd);
//填充服务器的地址信息结构体
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(IP);
char c = 0;
while (1)
{
printf("请选择:\n\t 1>下载\n\t 2>上传\n\t 3>退出\n");
c = getchar();
while (getchar() != 10)
printf("%c\n",c);
switch (c)
{
case '1':
do_download(cfd, sin);
break;
case '2':
do_upload(cfd, sin);
break;
case '3':
goto END;
default:
printf("输入错误,请重新输入:\n");
}
}
END:
//关闭文件描述符
close(cfd);
return 0;
}
int do_download(int cfd,struct sockaddr_in sin)
{
char name[20] = "";
printf("请输入文件名:");
scanf("%s", name);
while(getchar() != 10);
//组数据包
char buf[516] = "";
unsigned short *ptr1 = (unsigned short *)buf;
*ptr1 = htons(1);
char *ptr2 = buf + 2;
strcpy(ptr2, name);
char *ptr3 = ptr2 + strlen(name);
*ptr3 = 0;
char *ptr4 = ptr3 + 1;
strcpy(ptr4, "octet");
int size = 2 + 2 + 1 + strlen(ptr2) + strlen(ptr4);
//发送下载请求给服务器
if (sendto(cfd, buf, size, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
{
ERR_MSG("sendto 下载请求");
return -1;
}
printf("发送下载请求给服务器成功\n");
//打开一个用于写入的文件
int fd = open(ptr2, O_WRONLY|O_CREAT|O_APPEND, 0664);
if(fd < 0)
{
ERR_MSG("fd err");
return -1;
}
while(1)
{
bzero(buf, sizeof(buf));
socklen_t addlen = sizeof(sin);
int res = 0;
if((res = recvfrom(cfd, buf, sizeof(buf), 0, (struct sockaddr *)&sin, &addlen)) < -1)
{
ERR_MSG("recvfrom");
return -1;
}
//写入本地
char *data = buf + 4;
write(fd, data, 512);
//组ACK包
unsigned short net = *(ptr1 + 1);
bzero(buf, sizeof(buf));
*ptr1 = htons(4);
*(ptr1 + 1) = net;
//回复ACK
if(sendto(cfd, buf, 4, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
{
ERR_MSG("sendto");
return -1;
}
//判断数据是否小于512,若小于512,则传输结束
if(res<516)
break;
}
close(fd);
return -1;
}
int do_upload(int cfd, struct sockaddr_in sin)
{
char name[20] = "";
printf("请输入文件名:");
scanf("%s", name);
while(getchar() != 10);
//组数据包
char buf[516] = "";
unsigned short *ptr1 = (unsigned short *)buf;
*ptr1 = htons(2);
char *ptr2 = buf + 2;
strcpy(ptr2, name);
char *ptr3 = ptr2 + strlen(name);
*ptr3 = 0;
char *ptr4 = ptr3 + 1;
strcpy(ptr4, "octet");
int size = 2 + 2 + 1 + strlen(ptr2) + strlen(ptr4);
//发送上传请求给服务器
if (sendto(cfd, buf, size, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
{
ERR_MSG("sendto 上传请求");
return -1;
}
printf("发送上传请求给服务器成功\n");
// 获取服务器的临时端口
struct sockaddr_in tem_sin;
socklen_t addrlen = sizeof(tem_sin);
// 接收服务器发来的包
bzero(buf, sizeof(buf));
if (recvfrom(cfd, buf, sizeof(buf), 0, (struct sockaddr*)&tem_sin, &addrlen) < 0)
{
ERR_MSG("recvfrom error");
}
// 打开上传的文件
int fd = open("./1.c", O_RDONLY);
if (fd < 0)
{
ERR_MSG("open error");
return -1;
}
while (1)
{
unsigned short net = *(ptr1 + 1);
bzero(buf, sizeof(buf));
// 组数据包
*ptr1 = htons(3);
*(ptr1 + 1) = net;
int res = 0;
// 发送数据包
res = sendto(cfd, buf, sizeof(buf), 0, (struct sockaddr*)&tem_sin, sizeof(tem_sin));
if (res < 0)
{
ERR_MSG("sendto error");
return -1;
}
//判断数据是否小于512,若小于512,则传输结束
if(res<516)
break;
// 接收并检验服务器发来的包
bzero(buf, sizeof(buf));
if (recvfrom(cfd, buf, sizeof(buf), 0, (struct sockaddr*)&tem_sin, &addrlen) < 0)
{
ERR_MSG("recvfrom error");
return -1;
}
}
return 0;
}