C++中Socket网络编程实例详解
Socket是一种封装了TCP/IP协议的编程接口,常用于网络编程中。在C语言中,使用Socket进行网络编程可以极大地扩展程序的功能。下面我们将介绍一个简单的Socket网络编程实例,帮助读者了解Socket网络编程的基本使用方法。
1. 创建Socket
在C语言中,可以使用socket函数创建一个Socket,函数定义如下:
#include <sys/socket.h> int socket(int domain, int type, int protocol);
其中,domain参数指定Socket的协议族,type参数指定Socket的类型,protocol参数指定所使用的协议。常用的协议族有AF_INET(IPv4)和AF_INET6(IPv6),常用的Socket类型有SOCK_STREAM(面向连接的套接字)和SOCK_DGRAM(无连接套接字),常用的协议有TCP和UDP。
下面是一个创建TCP的Socket的示例代码:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORT 12345
int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in serv_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("ERROR opening socket");
exit(1);
}
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(PORT);
if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
perror("ERROR on binding");
exit(1);
}
listen(sockfd, 5);
return 0;
}
在这个例子中,我们使用socket函数创建了一个TCP的Socket,并将其绑定到本地的一个端口上。listen函数则将这个Socket置于监听状态,以便随时能够接收来自客户端的请求。
2. 接收客户端请求
当服务器程序启动并开始监听后,就可以接收来自客户端的请求了。在C语言中,使用accept函数接收客户端的连接请求,函数定义如下:
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
其中,sockfd参数是监听Socket的文件描述符,addr参数是用于存放客户端地址信息的结构体指针,addrlen参数则是addr结构体的大小。
接下来是一个简单的Socket服务器程序的示例代码,程序运行后会一直在等待客户端请求:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORT 12345
int main(int argc, char **argv)
{
int sockfd, newsockfd;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("ERROR opening socket");
exit(1);
}
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(PORT);
if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
perror("ERROR on binding");
exit(1);
}
listen(sockfd, 5);
clilen = sizeof(cli_addr);
while (1)
{
newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
if (newsockfd < 0)
{
perror("ERROR on accept");
exit(1);
}
/* Do something with the new client connected */
close(newsockfd);
}
return 0;
}
3. 向客户端发送数据
在Socket网络编程中,服务器程序可以通过向客户端发送数据来处理客户端请求。在C语言中,可以使用send函数向客户端发送数据,函数定义如下:
#include <sys/types.h> #include <sys/socket.h> ssize_t send(int sockfd, const void *buf, size_t len, int flags);
其中,sockfd参数是Socket的文件描述符,buf参数是发送数据的缓冲区,len参数是缓冲区中要发送的数据的长度,flags参数则指定传输时的各种选项,一般默认为0。
下面是一个简单的实例,向客户端发送一条Hello World消息:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORT 12345
int main(int argc, char **argv)
{
int sockfd, newsockfd;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
char *message = "Hello World!";
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("ERROR opening socket");
exit(1);
}
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(PORT);
if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
perror("ERROR on binding");
exit(1);
}
listen(sockfd, 5);
clilen = sizeof(cli_addr);
while (1)
{
newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
if (newsockfd < 0)
{
perror("ERROR on accept");
exit(1);
}
send(newsockfd, message, strlen(message), 0);
close(newsockfd);
}
return 0;
}
4. 接收客户端数据
当服务器向客户端发送了数据后,客户端也可以向服务器发送数据。在C语言中,可以使用recv函数接收客户端传来的数据,函数定义如下:
#include <sys/types.h> #include <sys/socket.h> ssize_t recv(int sockfd, void *buf, size_t len, int flags);
其中,sockfd参数是Socket的文件描述符,buf参数是接收数据的缓冲区,len参数是缓冲区的长度,flags则是传输选项,一般默认为0。
下面是一个简单的实例,接收来自客户端的一条消息:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORT 12345
int main(int argc, char **argv)
{
int sockfd, newsockfd, n;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
char buffer[256];
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("ERROR opening socket");
exit(1);
}
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(PORT);
if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
perror("ERROR on binding");
exit(1);
}
listen(sockfd, 5);
clilen = sizeof(cli_addr);
while (1)
{
newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
if (newsockfd < 0)
{
perror("ERROR on accept");
exit(1);
}
memset(buffer, 0, sizeof(buffer));
n = recv(newsockfd, buffer, sizeof(buffer), 0);
if (n < 0)
{
perror("ERROR reading from socket");
exit(1);
}
printf("Message from client: %s
", buffer);
close(newsockfd);
}
return 0;
}
通过读取来自客户端的传输,服务器可以进一步对请求进行处理。
总结
本文介绍了C语言中Socket网络编程的一些基础知识,包括创建Socket、接收客户端请求、向客户端发送数据和接收客户端数据等操作。Socket网络编程可以极大地扩展程序的功能,可以应用于网络通信、文件
