ARP
情况一:我与小胖位于同一子网。我向小胖的ip地址发起arp请求,小胖收到回应,告诉我他的mac地址,然后我向该mac地址发送hello即可。
情况二:我与小胖不在同一子网。由于不在同一子网,我需要向我的网关发送arp请求,网关告诉我mac地址,然后我向告诉网关:“向小胖的ip发hello”。剩下的事情,我就不用管了,如果网络可达,那么小胖就会收到我发的hello。
判断主机大小端
#include <iostream>
using namespace std;
int main()
{
union
{
short value;
char s[2];
} t;
t.value = 0x0102;
if (t.s[0] == 0x01)
cout << "大端" << endl;
else if (t.s[0] == 0x02)
cout << "小端" << endl;
return 0;
}
IP地址转换
#include <iostream>
#include <stdio.h>
#include <arpa/inet.h>
using namespace std;
int main()
{
char addr[] = "192.168.1.1";
unsigned int num = 0;
inet_pton(AF_INET, addr, &num);
unsigned char *p = (unsigned char *)#
printf("%d %d %d %d\n", *p, *(p + 1), *(p + 2), *(p + 3));
char show[16] = {0};
const char *res = inet_ntop(AF_INET, &num, show, sizeof(show));
cout << res << endl;
return 0;
}
例:server和client的通信
server
#include <stdio.h>
#include <arpa/inet.h>
#include <iostream>
#include <stdlib.h>
#include <string>
#include <cstring>
#include <unistd.h>
using namespace std;
void show(sockaddr_in caddr)
{
char cIP[16] = {0};
inet_ntop(AF_INET, &caddr.sin_addr.s_addr, cIP, sizeof(cIP));
unsigned short clientPort = ntohs(caddr.sin_port);
cout << cIP << ":" << clientPort << endl;
return;
}
int rcv(int opfd)
{
char rcvbuf[1024] = {0};
int len = read(opfd, rcvbuf, sizeof(rcvbuf));
if (len == -1)
{
perror("read");
exit(-1);
}
else if (len > 0)
cout << rcvbuf << endl;
else
{
cout << "client closed..." << endl;
return 0;
}
}
void sd(int opfd)
{
char sdbuf[1024] = {0};
cin >> sdbuf;
write(opfd, sdbuf, strlen(sdbuf));
}
int main()
{
int lfd = socket(AF_INET, SOCK_STREAM, 0);
if (lfd == -1)
{
perror("socket");
exit(-1);
}
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
inet_pton(AF_INET, "172.24.24.44", (void *)&saddr.sin_addr.s_addr);
//saddr.sin_addr.s_addr = INADDR_ANY; // 0.0.0.0
saddr.sin_port = htons(9999);
int ret = bind(lfd, (struct sockaddr *)&saddr, sizeof(saddr));
if (ret == -1)
{
perror("bind");
exit(-1);
}
ret = listen(lfd, 8);
if (ret == -1)
{
perror("litsen");
exit(-1);
}
struct sockaddr_in caddr;
socklen_t len = sizeof(caddr);
int opfd = accept(lfd, (struct sockaddr *)&caddr, &len);
if (opfd == -1)
{
perror("accept");
exit(-1);
}
show(caddr);
pid_t pid = fork();
if (pid > 0)
while (rcv(opfd));
else if (pid == 0)
{
while (1)
sd(opfd);
}
close(opfd);
close(lfd);
return 0;
}
client
#include <stdio.h>
#include <arpa/inet.h>
#include <iostream>
#include <stdlib.h>
#include <string>
#include <cstring>
#include <unistd.h>
using namespace std;
void sd(int fd)
{
char buf[1024] = {0};
cin >> buf;
write(fd, buf, sizeof(buf));
return;
}
int rcv(int fd)
{
char rcvbuf[1024] = {0};
int len = read(fd, rcvbuf, sizeof(rcvbuf));
if (len == -1)
{
perror("read");
exit(-1);
}
else if (len > 0)
cout << rcvbuf << endl;
else
{
cout << "client closed..." << endl;
return false;
}
return true;
}
int main()
{
int fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd == -1)
{
perror("socket");
exit(0);
}
struct sockaddr_in saddr;
saddr.sin_port = htons(9999);
inet_pton(AF_INET, "172.24.24.44", &saddr.sin_addr.s_addr);
saddr.sin_family = AF_INET;
int res = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
if (res == -1)
{
perror("conn");
exit(-1);
}
pid_t pid = fork();
if (pid > 0)
{
while (1)
sd(fd);
}
else if (pid == 0)
{
while (rcv(fd))
;
}
close(fd);
return 0;
}
多进程实现并发服务器
#include <stdio.h>
#include <arpa/inet.h>
#include <iostream>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <string>
#include <cstring>
#include <wait.h>
using namespace std;
void recyclechild(int arg)
{
while (1)
{
int ret = waitpid(-1, NULL, WNOHANG);
if (ret == -1)
break;
else if (ret == 0)
break;
else
cout << ret << "recycled" << endl;
}
}
int main()
{
struct sigaction act;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
act.sa_handler = recyclechild;
sigaction(SIGCHLD, &act, NULL);
int lfd = socket(AF_INET, SOCK_STREAM, 0);
if (lfd == -1)
{
perror("link");
exit(-1);
}
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(9999);
saddr.sin_addr.s_addr = INADDR_ANY;
int res = bind(lfd, (struct sockaddr *)&saddr, sizeof(saddr));
if (res == -1)
{
perror("bind");
exit(-1);
}
res = listen(lfd, 128);
if (res == -1)
{
perror("listen");
exit(-1);
}
while (1)
{
struct sockaddr_in caddr;
socklen_t len = sizeof(caddr);
int cfd = accept(lfd, (struct sockaddr *)&caddr, &len);
if (cfd == -1)
{
if (errno == EINTR)
continue;
perror("accept");
exit(-1);
}
pid_t pid = fork();
if (pid == 0)
{
char cIP[16];
inet_ntop(AF_INET, &caddr.sin_addr.s_addr, cIP, sizeof(cIP));
unsigned short cPort = ntohs(caddr.sin_port);
cout << cIP << ':' << cPort << endl;
char buf[1024] = {0};
int len = 0;
while (len = read(cfd, buf, sizeof(buf)) > 0)
{
cout << buf << endl;
write(cfd, "recieved", strlen("recieved"));
}
if (len == 0)
cout << "client " << cIP << ':' << cPort << " closed..." << endl;
else
perror("read");
close(cfd);
exit(0);
}
else if (pid == -1)
{
perror("fork");
exit(-1);
}
}
close(lfd);
return 0;
}
select完成IO多路复用
#include <iostream>
#include <stdio.h>
#include <unistd.h>
#include <sys/select.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <cstring>
#include <string>
using namespace std;
int main()
{
int lfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in saddr;
saddr.sin_port = htons(9999);
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = INADDR_ANY;
bind(lfd, (struct sockaddr *)&saddr, sizeof(saddr));
listen(lfd, 8);
fd_set rdset, tmp;
FD_ZERO(&rdset);
FD_SET(lfd, &rdset);
int maxfd = lfd;
while (1)
{
tmp = rdset;
int res = select(maxfd + 1, &tmp, NULL, NULL, NULL);
if (res == -1)
{
perror("select");
exit(-1);
}
else if (res == 0)
continue;
else
{
if (FD_ISSET(lfd, &tmp))
{
int cfd;
struct sockaddr_in caddr;
unsigned int len = sizeof(caddr);
cfd = accept(lfd, (struct sockaddr *)&caddr, &len);
FD_SET(cfd, &rdset);
maxfd = max(maxfd, cfd);
}
for (int i = lfd + 1; i <= maxfd; ++i)
{
if (FD_ISSET(i, &tmp))
{
char buf[1024] = {0};
int len = read(i, buf, sizeof(buf));
if (len == -1)
{
perror("read");
exit(-1);
}
else if (len == 0)
{
cout << "closed..." << endl;
close(i);
FD_CLR(i, &rdset);
}
else
{
cout << buf << endl;
write(i, "recieved!", strlen("recieved!") + 1);
}
}
}
}
}
close(lfd);
return 0;
}
epoll服务端
#include <iostream>
#include <stdio.h>
#include <unistd.h>
#include <sys/select.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <cstring>
#include <string>
#include <sys/epoll.h>
using namespace std;
int main()
{
int lfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in saddr;
saddr.sin_port = htons(9999);
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = INADDR_ANY;
bind(lfd, (struct sockaddr *)&saddr, sizeof(saddr));
listen(lfd, 8);
int epfd = epoll_create(1);
struct epoll_event epev;
epev.events = EPOLLIN;
epev.data.fd = lfd;
epoll_ctl(epfd, EPOLL_CTL_ADD, lfd, &epev);
struct epoll_event epevs[1024];
while (1)
{
int ret = epoll_wait(epfd, epevs, 1024, -1);
if (ret == -1)
{
perror("epoll");
exit(-1);
}
cout << ret << endl;
for (int i = 0; i < ret; ++i)
{
int curfd = epevs[i].data.fd;
if (epevs[i].data.fd == lfd)
{
int cfd;
struct sockaddr_in caddr;
unsigned int len = sizeof(caddr);
cfd = accept(lfd, (struct sockaddr *)&caddr, &len);
epev.events = EPOLLIN;
epev.data.fd = cfd;
epoll_ctl(epfd, EPOLL_CTL_ADD, cfd, &epev);
}
else
{
char buf[1024] = {0};
int len = read(curfd, buf, sizeof(buf));
if (len == -1)
{
perror("read");
exit(-1);
}
else if (len == 0)
{
cout << "closed..." << endl;
close(curfd);
epoll_ctl(epfd, EPOLL_CTL_DEL, curfd, NULL);
}
else
{
cout << buf << endl;
write(curfd, "recieved!", strlen("recieved!") + 1);
}
}
}
}
close(epfd);
close(lfd);
return 0;
}
udp通信server
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <cstring>
#include <arpa/inet.h>
#include <iostream>
using namespace std;
int main()
{
int fd = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in addr;
addr.sin_port = htons(9999);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
bind(fd, (struct sockaddr *)&addr, sizeof(addr));
while (1)
{
char buf[1024] = {0};
char ipbuf[16] = {0};
struct sockaddr_in caddr;
socklen_t len = sizeof(caddr);
recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&caddr, &len);
cout << inet_ntop(AF_INET, &caddr.sin_addr.s_addr, ipbuf, sizeof(ipbuf)) << ':' << caddr.sin_port << endl;
cout << buf << endl;
sendto(fd, buf, strlen(buf) + 1, 0, (struct sockaddr *)&caddr, len);
}
close(fd);
return 0;
}
udp通信client
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <cstring>
#include <arpa/inet.h>
#include <iostream>
using namespace std;
int main()
{
int fd = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in addr;
addr.sin_port = htons(9999);
addr.sin_family = AF_INET;
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
socklen_t len = sizeof(addr);
//bind(fd, (struct sockaddr *)&addr, sizeof(addr));
int cnt = 0;
while (1)
{
char buf[1024] = {0};
sprintf(buf, "hello:%d\n", ++cnt);
sendto(fd, buf, strlen(buf) + 1, 0, (struct sockaddr *)&addr, len);
recvfrom(fd, buf, sizeof(buf), 0, NULL, NULL);
cout << buf << endl;
sleep(1);
}
close(fd);
return 0;
}