一、结构体
结构体 |
功能 |
特性 |
struct sockaddr |
套接字地址结构 |
IPv4 / IPv6 |
struct sockaddr_in |
IPv4套接字地址结构 |
IPv4 |
struct in_addr |
IPv4地址结构 |
IPv4 |
struct sockaddr_in6 |
IPv6套接字地址结构 |
IPv6 |
| |
| struct sockaddr |
| { |
| unsigned short sa_family; |
| char sa_data[14]; |
| }; |
| |
| |
| struct sockaddr_in |
| { |
| short sin_family; |
| unsigned short sin_port; |
| struct in_addr sin_addr; |
| unsigned char sin_zero[8]; |
| }; |
| |
| |
| typedef unsigned int in_addr_t; |
| |
| |
| struct in_addr |
| { |
| in_addr_t s_addr; |
| }; |
| |
| |
| struct sockaddr_in6 |
| { |
| uint8_t sin6_len; |
| sa_family_t sin6_family; |
| in_port_t sin6_port; |
| uint32_t sin6_flowinfo; |
| struct in6_addr sin6_addr; |
| }; |
二、转换接口
头文件:arpa/inet.h
1、字节序转换
函数 |
作用 |
ntohs() |
将unsigned short 类型从网络序转换到主机序 |
ntohl() |
将unsigned long 类型从网络序转换到主机序 |
函数 |
作用 |
htons() |
将unsigned short 类型从主机序转换到网络序 |
htonl() |
将unsigned long 类型从主机序转换到网络序 |
实例:
| #include <iostream> |
| #include <cstring> |
| #include <iomanip> |
| #include <arpa/inet.h> |
| |
| void Hex(int n) |
| { |
| char bytes[2]; |
| memcpy(bytes, &n, 2); |
| std::cout << showbase << setw(2) << setfill('0') |
| << hex << (int)bytes[0] << setw(2) << (int)bytes[1] << std::endl; |
| } |
| |
| int main() |
| { |
| uint16_t n = 16; |
| Hex(n); |
| |
| uint16_t m = htons(n); |
| Hex(m); |
| |
| uint16_t t = ntohs(m); |
| Hex(t); |
| |
| return 0; |
| } |
2、IP地址转换
函数 |
功能 |
特点 |
int inet_aton(const char *string, struct in_addr *addr) |
点分十进制数串转长整型网络字节序 |
IPv4 |
in_addr_t inet_addr(const char *string) |
点分十进制数串转长整型网络字节序 |
IPv4 |
char* inet_ntoa(struct in_addr addr) |
长整型网络字节序转点分十进制数串 |
IPv4 |
int inet_pton(int af, const char *src, void *dst) |
点分十进制数串转长整型网络字节序 |
IPv4 / IPv6 |
const char* inet_ntop(int af, const void *src, char *dst, socklen_t cnt) |
长整型网络字节序转点分十进制数串 |
IPv4 / IPv6 |
实例:
| #include <iostream> |
| #include <cstring> |
| #include <arpa/inet.h> |
| |
| int main() |
| { |
| std::string s = "192.168.0.1"; |
| struct in_addr addr; |
| inet_aton(s.c_str(), &addr); |
| std::cout << hex << addr.s_addr << "\n" |
| << inet_ntoa(addr) << "\n" |
| << inet_addr(s.c_str()) << std::endl; |
| |
| return 0; |
| } |
3、主机名转换
函数 |
功能 |
struct hostent* gethostbyname(const char *hostname) |
主机名转地址 |
struct hostent* gethostbyaddr(const char *addr, int len, int type) |
地址转主机名 |
参数 |
含义 |
h_name |
主机名 |
h_aliases |
以空指针结尾的主机别名队列 |
h_addrtype |
地址类型,AF_INET / AF_INET6 |
h_length |
地址长度,在AF_INET 类型地址中为4 |
h_addr |
第一个IP地址 |
h_addr_list |
以空指针结尾的IP地址的列表 |
三、Socket操作
头文件:sys/socket.h
1、创建
| |
| |
| |
| |
| |
| |
| |
| |
| |
| int socket(int domain, int type, int protocol); |
2、关闭
| |
| |
| |
| |
| |
| |
| |
| |
| int close(int sockfd); |
| int shutdown(int sockfd, int howto); |
| |
| |
| |
| |
3、属性
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen); |
4、获取
| int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen); |
5、绑定
| |
| |
| |
| |
| |
| |
| |
| |
| |
| int bind(int socket, const struct sockaddr *address, socklen_t address_len); |
6、监听
| |
| |
| |
| |
| |
| |
| |
| |
| int listen(int sockfd, int backlog); |
7、连接
| |
| |
| |
| |
| |
| |
| |
| |
| |
| int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); |
8、接收连接
| |
| |
| |
| |
| |
| |
| |
| |
| |
| int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); |
说明
如果不需要获取客户端套接字地址,addr
和addrlen
传入NULL
;
如果需要获取,参考如下例子:
| struct sockaddr_in remote_addr; |
| bzero(&remote_addr, sizeof(remote_addr)); |
| socklen_t remote_addr_len = sizeof(remote_addr); |
| |
| int connfd = accept(listenfd, (struct sockaddr*)&remote_addr, &remote_addr_len); |
9、发送数据
| |
| |
| |
| |
| |
| |
| |
| |
| |
| ssize_t write(int fd, const void *buf, size_t len); |
| ssize_t send(int sockfd, const void *buf, size_t len, int flags); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dst_addr, socklen_t addrlen); |
10、接收数据
| |
| |
| |
| |
| ssize_t read(int fd, void *buf, size_t len); |
| ssize_t recv(int sockfd, void *buf, size_t len, int flags); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen); |
四、TCP

1、客户端伪码
| main() |
| { |
| |
| fd = socket(); |
| |
| |
| connect(fd); |
| |
| |
| write(fd); |
| read(fd); |
| |
| |
| close(fd); |
| } |
2、服务端伪码
| main() |
| { |
| |
| fd = socket(); |
| |
| |
| bind(fd); |
| |
| |
| listen(fd, backlog); |
| |
| |
| connfd = accept(fd); |
| |
| |
| read(connfd); |
| write(connfd); |
| |
| |
| close(connfd); |
| close(fd); |
| } |
3、TCP 实例
| #include <iostream> |
| #include <string> |
| #include <unistd.h> |
| #include <sys/socket.h> |
| #include <sys/types.h> |
| #include <arpa/inet.h> |
| |
| |
| int Client() |
| { |
| int fd = socket(AF_INET, SOCK_STREAM, 0); |
| if(-1 == fd) |
| { |
| perror("open socket"); |
| return -1; |
| } |
| |
| sockaddr_in addr; |
| addr.sin_family = AF_INET; |
| inet_aton("127.0.0.1", &addr.sin_addr); |
| addr.sin_port = htons(8080); |
| |
| if(-1 == connect(fd, (struct sockaddr*)&addr, sizeof(addr))) |
| { |
| perror("connect"); |
| return -1; |
| } |
| |
| std::string s; |
| std::cin >> s; |
| write(fd, s.c_str(), s.size() + 1); |
| |
| char buf[256] = {0}; |
| read(fd, buf, 256); |
| std::cout << buf << std::endl; |
| |
| close(fd); |
| |
| return 0; |
| } |
| |
| |
| int Server() |
| { |
| int fd = socket(AF_INET, SOCK_STREAM, 0); |
| if(-1 == fd) |
| { |
| perror("open socket"); |
| return -1; |
| } |
| |
| struct sockaddr_in addr; |
| addr.sin_family = AF_INET; |
| inet_aton("127.0.0.1", &addr.sin_addr); |
| addr.sin_port = htons(8080); |
| |
| if(-1 == bind(fd, (struct sockaddr*)&addr, sizeof(addr))) |
| { |
| perror("bind"); |
| return -1; |
| } |
| |
| if(-1 == listen(fd, 4)) |
| { |
| perror("listen"); |
| return -1; |
| } |
| |
| int connfd = accept(fd, NULL, NULL); |
| if(-1 == connfd) |
| { |
| perror("accept"); |
| return -1; |
| } |
| |
| char buf[256] = {0}; |
| read(connfd, buf, 256); |
| std::cout << buf << std::endl; |
| |
| std::string s; |
| std::cin >> s; |
| write(connfd, s.c_str(), s.size() + 1); |
| |
| close(connfd); |
| close(fd); |
| |
| return 0; |
| } |
4、父子进程实例
| #include <iostream> |
| #include <string> |
| #include <unistd.h> |
| #include <sys/socket.h> |
| #include <sys/types.h> |
| #include <arpa/inet.h> |
| |
| using namespace std; |
| |
| |
| int main(int argc, char *argv[]) |
| { |
| if (3 != argc) |
| { |
| cout << "argument error" << "\n"; |
| cout << "Usage:" << argv[0] << "sever_ip sever_port" << endl; |
| return 1; |
| } |
| |
| int fd = socket(AF_INET, SOCK_STREAM, 0); |
| if (-1 == fd) |
| { |
| perror("open socket"); |
| return 1; |
| } |
| |
| struct sockaddr_in addr; |
| addr.sin_family = AF_INET; |
| inet_aton(argv[1], &addr.sin_addr); |
| addr.sin_port = htons(atoi(argv[2])); |
| |
| int res = connect(fd, (struct sockaddr *)&addr, sizeof(addr)); |
| if (-1 == res) |
| { |
| perror("connect"); |
| return 1; |
| } |
| |
| if (fork()) |
| { |
| string s; |
| while (cin >> s) |
| { |
| write(fd, s.c_str(), s.size() + 1); |
| } |
| } |
| else |
| { |
| for (;;) |
| { |
| char buffer[256] = {0}; |
| read(fd, buffer, 256); |
| cout << buffer << endl; |
| } |
| } |
| |
| close(fd); |
| |
| return 0; |
| } |
| |
| |
| int main(int argc, char *argv[]) |
| { |
| if (3 != argc) |
| { |
| cout << "argument error" << "\n"; |
| cout << "Usage:" << argv[0] << "sever_ip sever_port" << endl; |
| return 1; |
| } |
| |
| int fd = socket(AF_INET, SOCK_STREAM, 0); |
| if (-1 == fd) |
| { |
| perror("open socket"); |
| return 1; |
| } |
| |
| struct sockaddr_in addr; |
| addr.sin_family = AF_INET; |
| inet_aton(argv[1], &addr.sin_addr); |
| addr.sin_port = htons(atoi(argv[2])); |
| |
| int res = bind(fd, (struct sockaddr *)&addr, sizeof(addr)); |
| if (-1 == res) |
| { |
| perror("bind"); |
| return 1; |
| } |
| |
| res = listen(fd, 4); |
| if (-1 == res) |
| { |
| perror("listen"); |
| return 1; |
| } |
| |
| int connfd = accept(fd, NULL, NULL); |
| if (-1 == connfd) |
| { |
| perror("accept"); |
| return 1; |
| } |
| |
| if (fork()) |
| { |
| for (;;) |
| { |
| char buffer[256] = {0}; |
| read(connfd, buffer, 256); |
| cout << buffer << endl; |
| } |
| } |
| else |
| { |
| string s; |
| while (cin >> s) |
| { |
| write(connfd, s.c_str(), s.size() + 1); |
| } |
| } |
| |
| close(connfd); |
| close(fd); |
| |
| return 0; |
| } |
5、C++ 多线程实例
| #include <iostream> |
| #include <string> |
| #include <unistd.h> |
| #include <sys/socket.h> |
| #include <sys/types.h> |
| #include <arpa/inet.h> |
| #include <thread> |
| |
| using namespace std; |
| |
| |
| int main(int argc, char *argv[]) |
| { |
| if (3 != argc) |
| { |
| cout << "argument error" << "\n"; |
| cout << "Usage:" << argv[0] << "sever_ip sever_port" << endl; |
| return 1; |
| } |
| |
| int fd = socket(AF_INET, SOCK_STREAM, 0); |
| if (-1 == fd) |
| { |
| perror("open socket"); |
| return 1; |
| } |
| |
| struct sockaddr_in addr; |
| addr.sin_family = AF_INET; |
| inet_aton(argv[1], &addr.sin_addr); |
| addr.sin_port = htons(atoi(argv[2])); |
| |
| int res = connect(fd, (struct sockaddr *)&addr, sizeof(addr)); |
| if (-1 == res) |
| { |
| perror("connect"); |
| return 1; |
| } |
| |
| thread t([fd](){ |
| for(;;) |
| { |
| char buffer[256] = {0}; |
| int n = read(fd,buffer,256); |
| |
| if(0 == n) |
| { |
| cout << "sever exit!" << endl; |
| break; |
| } |
| cout << buffer << endl; |
| } |
| }); |
| |
| t.detach(); |
| |
| string s; |
| while (cin >> s) |
| { |
| write(fd, s.c_str(), s.size() + 1); |
| } |
| |
| close(fd); |
| |
| return 0; |
| } |
| |
| |
| int main(int argc, char *argv[]) |
| { |
| if (3 != argc) |
| { |
| cout << "argument error" << "\n"; |
| cout << "Usage:" << argv[0] << "sever_ip sever_port" << endl; |
| return 1; |
| } |
| |
| int fd = socket(AF_INET, SOCK_STREAM, 0); |
| if (-1 == fd) |
| { |
| perror("open socket"); |
| return 1; |
| } |
| |
| struct sockaddr_in addr; |
| addr.sin_family = AF_INET; |
| inet_aton(argv[1], &addr.sin_addr); |
| addr.sin_port = htons(atoi(argv[2])); |
| |
| int res = bind(fd, (struct sockaddr *)&addr, sizeof(addr)); |
| if (-1 == res) |
| { |
| perror("bind"); |
| return 1; |
| } |
| |
| res = listen(fd, 4); |
| if (-1 == res) |
| { |
| perror("listen"); |
| return 1; |
| } |
| |
| int connfd = accept(fd, NULL, NULL); |
| if (-1 == connfd) |
| { |
| perror("accept"); |
| return 1; |
| } |
| |
| thread t([connfd](){ |
| for(;;) |
| { |
| char buffer[256] = {0}; |
| int n = read(connfd,buffer,256); |
| if(0 == n) |
| { |
| cout << "client exit!" << endl; |
| break; |
| } |
| cout << buffer << endl; |
| } |
| }); |
| |
| t.detach(); |
| |
| string s; |
| while (cin >> s) |
| { |
| write(connfd, s.c_str(), s.size() + 1); |
| } |
| |
| close(connfd); |
| close(fd); |
| |
| return 0; |
| } |
6、多客户端实例
| #include <iostream> |
| #include <string> |
| #include <unistd.h> |
| #include <sys/socket.h> |
| #include <sys/types.h> |
| #include <arpa/inet.h> |
| #include <thread> |
| #include <vector> |
| |
| using namespace std; |
| |
| |
| int main(int argc, char *argv[]) |
| { |
| if (3 != argc) |
| { |
| cout << "argument error" << "\n"; |
| cout << "Usage:" << argv[0] << "sever_ip sever_port" << endl; |
| return 1; |
| } |
| |
| int fd = socket(AF_INET, SOCK_STREAM, 0); |
| if (-1 == fd) |
| { |
| perror("open socket"); |
| return 1; |
| } |
| |
| struct sockaddr_in addr; |
| addr.sin_family = AF_INET; |
| inet_aton(argv[1], &addr.sin_addr); |
| addr.sin_port = htons(atoi(argv[2])); |
| |
| int res = bind(fd, (struct sockaddr *)&addr, sizeof(addr)); |
| if (-1 == res) |
| { |
| perror("bind"); |
| return 1; |
| } |
| cout << "bind" << endl; |
| |
| res = listen(fd, 4); |
| if (-1 == res) |
| { |
| perror("listen"); |
| return 1; |
| } |
| cout << "listen" << endl; |
| |
| |
| vector<int> fds; |
| thread writer( |
| [&]() |
| { |
| string s; |
| while(cin >> s) |
| { |
| for(auto connfd : fds) |
| { |
| write(connfd, s.c_str(), s.size() + 1); |
| } |
| } |
| } |
| ); |
| |
| writer.detach(); |
| |
| for (;;) |
| { |
| struct sockaddr_in remote_addr; |
| socklen_t len = sizeof(remote_addr); |
| int connfd = accept(fd, (sockaddr *)&remote_addr, &len); |
| |
| |
| cout << inet_ntoa(remote_addr.sin_addr) << ":" << ntohs(remote_addr.sin_port) << endl; |
| |
| if (-1 == connfd) |
| { |
| perror("accept"); |
| return 1; |
| } |
| fds.push_back(connfd); |
| cout << "accept" << endl; |
| |
| thread t( |
| [connfd]() |
| { |
| for (;;) |
| { |
| char buffer[256] = {0}; |
| int n = read(connfd, buffer, 256); |
| if (0 == n) |
| { |
| cout << "client exit!" << endl; |
| break; |
| } |
| cout << buffer << endl; |
| } |
| } |
| ); |
| |
| t.detach(); |
| } |
| |
| for (auto connfd : fds) |
| { |
| close(connfd); |
| } |
| close(fd); |
| |
| return 0; |
| } |
7、文件服务器实例
| #include <iostream> |
| #include <string> |
| #include <unistd.h> |
| #include <sys/socket.h> |
| #include <sys/sendfile.h> |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #include <fcntl.h> |
| #include <arpa/inet.h> |
| #include <thread> |
| #include <vector> |
| |
| using namespace std; |
| |
| |
| int main(int argc, char *argv[]) |
| { |
| if (3 != argc) |
| { |
| cout << "argument error" << "\n"; |
| cout << "Usage:" << argv[0] << "sever_ip sever_port" << endl; |
| return 1; |
| } |
| |
| int fd = socket(AF_INET, SOCK_STREAM, 0); |
| if (-1 == fd) |
| { |
| perror("open socket"); |
| return 1; |
| } |
| |
| struct sockaddr_in addr; |
| addr.sin_family = AF_INET; |
| inet_aton(argv[1], &addr.sin_addr); |
| addr.sin_port = htons(atoi(argv[2])); |
| |
| int res = connect(fd, (struct sockaddr *)&addr, sizeof(addr)); |
| if (-1 == res) |
| { |
| perror("connect"); |
| return 1; |
| } |
| |
| string s; |
| cin >> s; |
| write(fd, s.c_str(), s.size() + 1); |
| |
| int pos = s.find_last_of('/'); |
| |
| |
| if (pos != string::npos) |
| { |
| s = s.substr(pos); |
| } |
| string file = "./" + s; |
| cout << file << endl; |
| |
| int filefd = open(file.c_str(), O_CREAT | O_WRONLY, 0666); |
| if (-1 == filefd) |
| { |
| perror("open file"); |
| return 1; |
| } |
| |
| |
| for (;;) |
| { |
| char buffer[256] = {0}; |
| int n = read(fd, buffer, 256); |
| write(filefd, buffer, n); |
| if (n < 256) |
| { |
| break; |
| } |
| } |
| |
| close(filefd); |
| close(fd); |
| |
| return 0; |
| } |
| |
| |
| int main(int argc, char *argv[]) |
| { |
| if (4 != argc) |
| { |
| cout << "argument error" << "\n"; |
| cout << "Usage:" << argv[0] << "sever_ip sever_port path" << endl; |
| return 1; |
| } |
| |
| int fd = socket(AF_INET, SOCK_STREAM, 0); |
| if (-1 == fd) |
| { |
| perror("open socket"); |
| return 1; |
| } |
| |
| struct sockaddr_in addr; |
| addr.sin_family = AF_INET; |
| inet_aton(argv[1], &addr.sin_addr); |
| addr.sin_port = htons(atoi(argv[2])); |
| |
| int res = bind(fd, (struct sockaddr *)&addr, sizeof(addr)); |
| if (-1 == res) |
| { |
| perror("bind"); |
| return 1; |
| } |
| |
| res = listen(fd, 4); |
| if (-1 == res) |
| { |
| perror("listen"); |
| return 1; |
| } |
| |
| int connfd = accept(fd, NULL, NULL); |
| if (-1 == connfd) |
| { |
| perror("accept"); |
| return 1; |
| } |
| |
| char buffer[256] = {0}; |
| read(connfd, buffer, 256); |
| cout << buffer << endl; |
| |
| string file = string(argv[3]) + "/" + buffer; |
| cout << "require " << file.c_str() << endl; |
| |
| int filefd = open(file.c_str(), O_RDONLY); |
| if (-1 == filefd) |
| { |
| perror("open file"); |
| return 1; |
| } |
| |
| struct stat s; |
| fstat(filefd, &s); |
| sendfile(connfd, filefd, 0, s.st_size); |
| |
| close(connfd); |
| close(fd); |
| |
| return 0; |
| } |
8、多客户端文件服务
| #include <iostream> |
| #include <string> |
| #include <unistd.h> |
| #include <sys/socket.h> |
| #include <sys/sendfile.h> |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #include <fcntl.h> |
| #include <arpa/inet.h> |
| #include <thread> |
| #include <vector> |
| |
| using namespace std; |
| |
| |
| int main(int argc, char *argv[]) |
| { |
| if (3 != argc) |
| { |
| cout << "argument error" << "\n"; |
| cout << "Usage:" << argv[0] << "sever_ip sever_port" << endl; |
| return 1; |
| } |
| |
| int fd = socket(AF_INET, SOCK_STREAM, 0); |
| if (-1 == fd) |
| { |
| perror("open socket"); |
| return 1; |
| } |
| |
| struct sockaddr_in addr; |
| addr.sin_family = AF_INET; |
| inet_aton(argv[1], &addr.sin_addr); |
| addr.sin_port = htons(atoi(argv[2])); |
| |
| int res = connect(fd, (struct sockaddr *)&addr, sizeof(addr)); |
| if (-1 == res) |
| { |
| perror("connect"); |
| return 1; |
| } |
| |
| for (;;) |
| { |
| char buffer[1024] = {0}; |
| int n = read(fd, buffer, 1024); |
| write(STDOUT_FILENO, buffer, n); |
| if (n < 1024) |
| { |
| break; |
| } |
| } |
| |
| string s; |
| while (cin >> s) |
| { |
| write(fd, s.c_str(), s.size() + 1); |
| |
| int pos = s.find_last_of('/'); |
| |
| if (pos != string::npos) |
| { |
| s = s.substr(pos); |
| } |
| string file = "./" + s; |
| cout << file << endl; |
| |
| int filefd = open(file.c_str(), O_CREAT | O_WRONLY, 0666); |
| if (-1 == filefd) |
| { |
| perror("open file"); |
| return 1; |
| } |
| |
| |
| for (;;) |
| { |
| char buffer[256] = {0}; |
| int n = read(fd, buffer, 256); |
| write(filefd, buffer, n); |
| if (n < 256) |
| { |
| break; |
| } |
| } |
| close(filefd); |
| } |
| close(fd); |
| |
| return 0; |
| } |
| |
| |
| int main(int argc, char *argv[]) |
| { |
| if (4 != argc) |
| { |
| cout << "argument error" << "\n"; |
| cout << "Usage:" << argv[0] << "sever_ip sever_port path" << endl; |
| return 1; |
| } |
| |
| int fd = socket(AF_INET, SOCK_STREAM, 0); |
| if (-1 == fd) |
| { |
| perror("open socket"); |
| return 1; |
| } |
| |
| struct sockaddr_in addr; |
| addr.sin_family = AF_INET; |
| inet_aton(argv[1], &addr.sin_addr); |
| addr.sin_port = htons(atoi(argv[2])); |
| |
| int res = bind(fd, (struct sockaddr *)&addr, sizeof(addr)); |
| if (-1 == res) |
| { |
| perror("bind"); |
| return 1; |
| } |
| |
| res = listen(fd, 4); |
| if (-1 == res) |
| { |
| perror("listen"); |
| return 1; |
| } |
| |
| for (;;) |
| { |
| int connfd = accept(fd, NULL, NULL); |
| if (-1 == connfd) |
| { |
| perror("accept"); |
| return 1; |
| } |
| |
| string cmd = string("ls -lR ") + argv[3]; |
| FILE *pfile = popen(cmd.c_str(), "r"); |
| if (NULL == pfile) |
| { |
| perror("popen"); |
| return 1; |
| } |
| |
| for (;;) |
| { |
| char info[1025] = {0}; |
| int n = fread(info, 1, 1024, pfile); |
| write(connfd, info, n); |
| if (n < 1024) |
| { |
| break; |
| } |
| } |
| pclose(pfile); |
| |
| thread t( |
| [=]() |
| { |
| for(;;) |
| { |
| char buffer[256] = {0}; |
| int n = read(connfd,buffer,256); |
| if(n <= 0) |
| { |
| break; |
| } |
| cout << buffer << endl; |
| |
| |
| string file = string(argv[3]) + "/" + buffer; |
| cout << "require " << file.c_str() << endl; |
| |
| int filefd = open(file.c_str(), O_RDONLY); |
| if(-1 == filefd) |
| { |
| perror("open file"); |
| return; |
| } |
| |
| struct stat s; |
| fstat(filefd, &s); |
| sendfile(connfd, filefd, 0, s.st_size); |
| } |
| close(connfd); |
| } |
| ); |
| t.detach(); |
| } |
| close(fd); |
| |
| return 0; |
| } |
五、UDP

1、单播
| |
| main() |
| { |
| |
| connfd = socket(AF_INET, SOCK_DGRAM, 0); |
| |
| |
| struct sockaddr_in si; |
| si.sin_family = AF_INET; |
| si.sin_port = htons(port); |
| si.sin_addr.s_addr = inet_addr(ip); |
| |
| |
| sendto(connfd, buf, buf_size, 0, (struct sockadrr *)&si, sizeof(si)); |
| |
| |
| close(connfd); |
| } |
| |
| |
| main() |
| { |
| |
| connfd = socket(AF_INET, SOCK_DGRAM, 0); |
| |
| |
| struct sockaddr_in si; |
| si.sin_family = AF_INET; |
| si.sin_port = htons(port); |
| si.sin_addr.s_addr = INADDR_ANY; |
| |
| |
| bind(connfd, (struct socket *)&si, sizeof(si)); |
| |
| |
| recv(connfd, buf, buf_size, 0); |
| |
| |
| close(connfd); |
| } |
| #include <iostream> |
| #include <string> |
| #include <unistd.h> |
| #include <sys/socket.h> |
| #include <sys/types.h> |
| #include <arpa/inet.h> |
| |
| using namespace std; |
| |
| |
| int main(int argc, char *argv[]) |
| { |
| if (3 != argc) |
| { |
| cout << "argument error" << "\n"; |
| cout << "Usage:" << argv[0] << "send_ip send_port" << endl; |
| return 1; |
| } |
| |
| int fd = socket(AF_INET, SOCK_DGRAM, 0); |
| if (-1 == fd) |
| { |
| perror("open socket"); |
| return 1; |
| } |
| |
| struct sockaddr_in addr; |
| addr.sin_family = AF_INET; |
| inet_aton(argv[1], &addr.sin_addr); |
| addr.sin_port = htons(atoi(argv[2])); |
| |
| string s; |
| getline(cin, s); |
| sendto(fd, s.c_str(), s.size() + 1, 0, (struct sockaddr *)&addr, sizeof(addr)); |
| |
| close(fd); |
| |
| return 0; |
| } |
| |
| |
| int main(int argc, char *argv[]) |
| { |
| if (3 != argc) |
| { |
| cout << "argument error" << "\n"; |
| cout << "Usage:" << argv[0] << "recv_ip recv_port" << endl; |
| return 1; |
| } |
| |
| int fd = socket(AF_INET, SOCK_DGRAM, 0); |
| if (-1 == fd) |
| { |
| perror("open socket"); |
| return 1; |
| } |
| |
| struct sockaddr_in addr; |
| addr.sin_family = AF_INET; |
| inet_aton(argv[1], &addr.sin_addr); |
| addr.sin_port = htons(atoi(argv[2])); |
| |
| bind(fd, (struct sockaddr *)&addr, sizeof(addr)); |
| |
| char buffer[1024] = {0}; |
| recv(fd, buffer, 1023, 0); |
| cout << buffer << endl; |
| |
| close(fd); |
| |
| return 0; |
| } |
| #include <iostream> |
| #include <string> |
| #include <unistd.h> |
| #include <sys/socket.h> |
| #include <sys/types.h> |
| #include <arpa/inet.h> |
| |
| using namespace std; |
| |
| |
| int main(int argc, char *argv[]) |
| { |
| if (3 != argc) |
| { |
| cout << "argument error" << endl; |
| cout << "Usage:" << argv[0] << "send_ip send_port" << endl; |
| return 1; |
| } |
| |
| int fd = socket(AF_INET, SOCK_DGRAM, 0); |
| if (-1 == fd) |
| { |
| perror("open socket"); |
| return 1; |
| } |
| |
| struct sockaddr_in addr; |
| addr.sin_family = AF_INET; |
| inet_aton(argv[1], &addr.sin_addr); |
| addr.sin_port = htons(atoi(argv[2])); |
| |
| string s; |
| getline(cin, s); |
| sendto(fd, s.c_str(), s.size() + 1, 0, (struct sockaddr *)&addr, sizeof(addr)); |
| |
| char buffer[1024] = {0}; |
| recv(fd, buffer, 1023, 0); |
| cout << buffer << endl; |
| |
| close(fd); |
| |
| return 0; |
| } |
| |
| |
| int main(int argc, char *argv[]) |
| { |
| if (3 != argc) |
| { |
| cout << "argument error" << endl; |
| cout << "Usage:" << argv[0] << "recv_ip recv_port" << endl; |
| return 1; |
| } |
| |
| int fd = socket(AF_INET, SOCK_DGRAM, 0); |
| if (-1 == fd) |
| { |
| perror("open socket"); |
| return 1; |
| } |
| |
| struct sockaddr_in addr; |
| addr.sin_family = AF_INET; |
| inet_aton(argv[1], &addr.sin_addr); |
| addr.sin_port = htons(atoi(argv[2])); |
| |
| bind(fd, (struct sockaddr *)&addr, sizeof(addr)); |
| char buffer[1024] = {0}; |
| |
| struct sockaddr_in remote_addr; |
| socklen_t len = sizeof(remote_addr); |
| recvfrom(fd, buffer, 1023, 0, (struct sockaddr *)&remote_addr, &len); |
| cout << buffer << endl; |
| |
| string s; |
| getline(cin, s); |
| sendto(fd, s.c_str(), s.size() + 1, 0, (struct sockaddr *)&remote_addr, len); |
| |
| close(fd); |
| |
| return 0; |
| } |
2、多播 / 组播
| |
| |
| |
| main() |
| { |
| |
| fd = socket(AF_INET, SOCK_DGRAM, 0); |
| |
| |
| struct sockaddr_in server_addr; |
| bzero(&server_addr, sizeof(server_addr)); |
| server_addr.sin_family = AF_INET; |
| server_addr.sin_addr.s_addr = htonl(INADDR_ANY); |
| server_addr.sin_port = htons(port); |
| |
| |
| bind(fd, server_addr, sizeof(server_addr)); |
| |
| |
| struct ip_mreqn group; |
| inet_pton(AF_INET, GROUP, &group.imr_multiaddr); |
| inet_pton(AF_INET, "0.0.0.0", &group.imr_address); |
| group.imr_ifindex = if_nametoindex("ent0"); |
| |
| |
| setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &group, sizeof(group)); |
| |
| |
| struct sockaddr_in cliaddr; |
| bzero(&cliaddr, sizeof(cliaddr)); |
| cliaddr.sin_family = AF_INET; |
| inet_pton(AF_INET, GROUP, &cliaddr.sin.addr.s_addr); |
| cliaddr.sin_port = htons(CLIENT_PORT); |
| |
| |
| sendto(fd, buf, strlen(buf), 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr)); |
| |
| |
| close(fd); |
| } |
| #include <iostream> |
| #include <unistd.h> |
| #include <sys/socket.h> |
| #include <sys/types.h> |
| #include <arpa/inet.h> |
| |
| using namespace std; |
| |
| int main(int argc, char *argv[]) |
| { |
| if (4 != argc) |
| { |
| cout << "argument error" << endl; |
| cout << "Usage:" << argv[0] << "recv_ip recv_port multi_ip" << endl; |
| return 1; |
| } |
| |
| int fd = socket(AF_INET, SOCK_DGRAM, 0); |
| if (-1 == fd) |
| { |
| perror("open socket"); |
| return 1; |
| } |
| |
| struct sockaddr_in addr; |
| addr.sin_family = AF_INET; |
| inet_aton(argv[1], &addr.sin_addr); |
| addr.sin_port = htons(atoi(argv[2])); |
| |
| bind(fd, (struct sockaddr *)&addr, sizeof(addr)); |
| |
| struct ip_mreq group; |
| group.imr_multiaddr.s_addr = inet_addr(argv[3]); |
| group.imr_interface.s_addr = inet_addr(argv[1]); |
| |
| if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&group, sizeof(group)) < 0) |
| { |
| perror("Adding multicast group"); |
| close(fd); |
| return 1; |
| } |
| |
| char buffer[1024] = {0}; |
| recv(fd, buffer, 1023, 0); |
| cout << buffer << endl; |
| |
| close(fd); |
| |
| return 0; |
| } |
3、广播
| |
| |
| |
| main() |
| { |
| |
| cfd = socket(AF_INET, SOCK_DGRAM, 0); |
| |
| |
| setsockopt(cfd, SOL_SOCKET, SO_BROADCAST, &n, sizeof(n)); |
| |
| |
| struct sockaddr_in si; |
| si.sin_family = AF_INET; |
| si.sin_port = htons(port); |
| si.sin_addr.s_addr = inet_addr("255.255.255.255"); |
| |
| |
| sendto(cfd, buf, buf_size, 0, (struct sockaddr *)&si, sizeof(si)); |
| |
| |
| close(socket); |
| } |
| #include <iostream> |
| #include <string> |
| #include <unistd.h> |
| #include <sys/socket.h> |
| #include <sys/types.h> |
| #include <arpa/inet.h> |
| |
| using namespace std; |
| |
| int main(int argc, char *argv[]) |
| { |
| if (3 != argc) |
| { |
| cout << "argument error" << endl; |
| cout << "Usage:" << argv[0] << "send_ip send_port" << endl; |
| return 1; |
| } |
| |
| int fd = socket(AF_INET, SOCK_DGRAM, 0); |
| if (-1 == fd) |
| { |
| perror("open socket"); |
| return 1; |
| } |
| |
| int opt = 1; |
| if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char *)&opt, sizeof(opt)) == -1) |
| { |
| perror("setsockopt"); |
| close(fd); |
| return 1; |
| } |
| |
| struct sockaddr_in addr; |
| addr.sin_family = AF_INET; |
| inet_aton(argv[1], &addr.sin_addr); |
| addr.sin_port = htons(atoi(argv[2])); |
| |
| string s; |
| getline(cin, s); |
| sendto(fd, s.c_str(), s.size() + 1, 0, (struct sockaddr *)&addr, sizeof(addr)); |
| |
| close(fd); |
| |
| return 0; |
| } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战