Socket通信是网络编程中的基本概念,它允许两个程序在不同主机上进行数据交换。在C语言中,Socket编程是非常基础且重要的技能。本文将详细介绍如何使用C语言进行Socket通信,包括实操步骤和实例详解。
一、Socket基础
1.1 什么是Socket?
Socket,即“套接字”,是网络通信中用于表示通信端点的一个抽象概念。在C语言中,Socket是一个文件描述符,它提供了读写网络数据的接口。
1.2 Socket类型
- 流式Socket(SOCK_STREAM):提供可靠的、面向连接的服务,例如TCP协议。
- 数据报Socket(SOCK_DGRAM):提供无连接的服务,数据报发送后,发送者和接收者之间没有任何关系,例如UDP协议。
二、创建Socket
在C语言中,使用socket()函数创建Socket。该函数原型如下:
int socket(int domain, int type, int protocol);
其中:
domain:指定协议族,常用的有AF_INET(IPv4)和AF_INET6(IPv6)。type:指定Socket类型,如SOCK_STREAM或SOCK_DGRAM。protocol:指定协议,对于流式Socket通常设为0,由系统自动选择。
三、绑定Socket
创建Socket后,需要将其绑定到一个具体的地址和端口上。这可以通过bind()函数实现:
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
其中:
sockfd:要绑定的Socket描述符。addr:指向sockaddr结构的指针,包含要绑定的地址和端口。addrlen:sockaddr结构的大小。
四、监听和连接
对于服务器端,需要调用listen()函数来监听传入的连接请求:
int listen(int sockfd, int backlog);
对于客户端,使用connect()函数连接到服务器:
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
五、数据传输
在建立连接后,可以使用send()和recv()函数进行数据传输:
int send(int sockfd, const void *buf, size_t len, int flags);
int recv(int sockfd, void *buf, size_t len, int flags);
其中:
send():发送数据。recv():接收数据。
六、实例详解
以下是一个简单的TCP服务器和客户端示例:
6.1 服务器端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main() {
int sockfd, newsockfd;
socklen_t clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("ERROR opening socket");
exit(1);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(8080);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
perror("ERROR on binding");
exit(1);
}
listen(sockfd, 5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0) {
perror("ERROR on accept");
exit(1);
}
while (1) {
bzero(buffer, 256);
n = read(newsockfd, buffer, 255);
if (n < 0) {
perror("ERROR reading from socket");
exit(1);
}
printf("Here is the message: %s\n", buffer);
n = write(newsockfd, buffer, strlen(buffer));
if (n < 0) {
perror("ERROR writing to socket");
exit(1);
}
}
close(newsockfd);
close(sockfd);
return 0;
}
6.2 客户端
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main() {
int sockfd, n;
char buffer[256];
struct sockaddr_in serv_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("ERROR opening socket");
exit(1);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(8080);
if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {
perror("ERROR, no such host");
exit(0);
}
if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
perror("ERROR connecting");
exit(1);
}
while (1) {
bzero(buffer, 256);
printf("Enter message: ");
fgets(buffer, 255, stdin);
n = write(sockfd, buffer, strlen(buffer));
if (n < 0) {
perror("ERROR writing to socket");
exit(1);
}
bzero(buffer, 256);
n = read(sockfd, buffer, 255);
if (n < 0) {
perror("ERROR reading from socket");
exit(1);
}
printf("%s\n", buffer);
}
close(sockfd);
return 0;
}
通过以上示例,你可以了解到使用C语言进行Socket通信的基本步骤和实例。希望这篇文章能帮助你轻松入门Socket通信!
