C++利用Socket实现主机间的UDP/TCP通信攻略
什么是Socket?
在计算机网络中,Socket又被称为“套接字”,是计算机之间通信的一种抽象,它是TCP/IP协议族中API的一部分,是支持TCP/IP协议的网络通信的基本操作单元,可以通过Socket在两台计算机之间建立连接,进行数据传输。
实现主机间的UDP通信
1. 创建一个UDP套接字
在C++中,采用socket函数创建socket套接字,其中domain代表协议族,type为套接字类型(传输控制协议TCP或用户数据报协议UDP),protocol指定协议编号。
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <iostream>
using namespace std;
int main() {
int sockfd;
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
cerr << "Can't create a UDP socket." << endl;
return 0;
}
return 0;
}
2. 绑定套接字
bind函数将一个socket与一个IP地址和端口号进行绑定。
struct sockaddr_in serveraddr;
memset(&serveraddr, 0, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons(8888);
if (bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) {
cerr << "Can't bind." << endl;
return 0;
}
3. 接收和发送数据包
使用recvfrom函数接收数据包,使用sendto函数发送数据包。
char buf[1024];
struct sockaddr_in clientaddr;
socklen_t clientlen = sizeof(clientaddr);
memset(&clientaddr, 0, sizeof(clientaddr));
while (true) {
memset(buf, 0, sizeof(buf));
if (recvfrom(sockfd, buf, sizeof(buf), 0,
(struct sockaddr *)&clientaddr, &clientlen) < 0) {
cerr << "Can't receive datagram." << endl;
}
cout << "Received: ";
cout.write(buf, strlen(buf));
cout << endl;
if (sendto(sockfd, buf, strlen(buf), 0,
(struct sockaddr *)&clientaddr, clientlen) < 0) {
cerr << "Can't send datagram." << endl;
}
}
实现主机间的TCP通信
1. 创建一个TCP套接字
创建TCP套接字与UDP套接字的步骤基本一致,只需要将第二个参数改为SOCK_STREAM即可。
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
cerr << "Can't create a TCP socket." << endl;
return 0;
}
2. 绑定套接字并开始监听
与UDP不同,TCP需要先绑定套接字并开始监听。使用listen函数进行监听。
struct sockaddr_in serveraddr;
memset(&serveraddr, 0, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons(8888);
if (bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) {
cerr << "Can't bind." << endl;
return 0;
}
if (listen(sockfd, 5) < 0) {
cerr << "Can't listen." << endl;
return 0;
}
3. 接受连接请求并发送数据
使用accept函数接受客户端的连接请求,使用send和recv函数进行数据的发送和接收。
int connfd;
struct sockaddr_in clientaddr;
socklen_t clientlen = sizeof(clientaddr);
memset(&clientaddr, 0, sizeof(clientaddr));
while (true) {
if ((connfd = accept(sockfd, (struct sockaddr *)&clientaddr, &clientlen)) < 0) {
cerr << "Can't accept." << endl;
return 0;
}
char sendline[] = "Hello, world!\n";
char recvline[1024];
memset(recvline, 0, sizeof(recvline));
if ((recv(connfd, recvline, sizeof(recvline), 0)) < 0) {
cerr << "Can't receive." << endl;
return 0;
}
cout << "Received: ";
cout.write(recvline, strlen(recvline));
cout << endl;
if ((send(connfd, sendline, strlen(sendline), 0)) < 0) {
cerr << "Can't send." << endl;
return 0;
}
close(connfd);
}
示例1:使用Socket实现基本的UDP通信
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <iostream>
using namespace std;
int main() {
int sockfd;
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
cerr << "Can't create a UDP socket." << endl;
return 0;
}
struct sockaddr_in serveraddr;
memset(&serveraddr, 0, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons(8888);
if (bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) {
cerr << "Can't bind." << endl;
return 0;
}
char buf[1024];
struct sockaddr_in clientaddr;
socklen_t clientlen = sizeof(clientaddr);
memset(&clientaddr, 0, sizeof(clientaddr));
while (true) {
memset(buf, 0, sizeof(buf));
if (recvfrom(sockfd, buf, sizeof(buf), 0,
(struct sockaddr *)&clientaddr, &clientlen) < 0) {
cerr << "Can't receive datagram." << endl;
}
cout << "Received: ";
cout.write(buf, strlen(buf));
cout << endl;
if (sendto(sockfd, buf, strlen(buf), 0,
(struct sockaddr *)&clientaddr, clientlen) < 0) {
cerr << "Can't send datagram." << endl;
}
}
close(sockfd);
return 0;
}
示例2:使用Socket实现基本的TCP通信
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <iostream>
using namespace std;
int main() {
int sockfd;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
cerr << "Can't create a TCP socket." << endl;
return 0;
}
struct sockaddr_in serveraddr;
memset(&serveraddr, 0, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons(8888);
if (bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) {
cerr << "Can't bind." << endl;
return 0;
}
if (listen(sockfd, 5) < 0) {
cerr << "Can't listen." << endl;
return 0;
}
int connfd;
struct sockaddr_in clientaddr;
socklen_t clientlen = sizeof(clientaddr);
memset(&clientaddr, 0, sizeof(clientaddr));
while (true) {
if ((connfd = accept(sockfd, (struct sockaddr *)&clientaddr, &clientlen)) < 0) {
cerr << "Can't accept." << endl;
return 0;
}
char sendline[] = "Hello, world!\n";
char recvline[1024];
memset(recvline, 0, sizeof(recvline));
if ((recv(connfd, recvline, sizeof(recvline), 0)) < 0) {
cerr << "Can't receive." << endl;
return 0;
}
cout << "Received: ";
cout.write(recvline, strlen(recvline));
cout << endl;
if ((send(connfd, sendline, strlen(sendline), 0)) < 0) {
cerr << "Can't send." << endl;
return 0;
}
close(connfd);
}
return 0;
}
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++利用Socket实现主机间的UDP/TCP通信 - Python技术站