在网络编程中,客户端和服务器端的交互是构建分布式系统的基础,使用C语言进行网络编程时,通常会涉及到套接字(socket)的使用,这是一种进程间通信的方式,下面将详细介绍如何使用C语言编写一个简单的客户端和服务器端程序。
服务端程序
1、创建套接字:需要创建一个套接字来监听客户端的连接请求,可以使用socket()函数来创建一个新的套接字,该函数的原型如下:
int socket(int domain, int type, int protocol);
domain指定协议族,常用的有AF_INET(IPv4)和AF_INET6(IPv6),type指定套接字类型,常用的有SOCK_STREAM(流套接字,用于TCP)和SOCK_DGRAM(数据报套接字,用于UDP),protocol通常设置为0,表示使用默认协议。
2、绑定套接字:需要将套接字绑定到一个特定的端口号和IP地址,可以使用bind()函数来完成这个操作:
struct sockaddr_in address; address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(PORT); if (bind(server_socket, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("bind failed"); close(server_socket); exit(EXIT_FAILURE); }
3、监听连接请求:绑定成功后,服务器需要开始监听来自客户端的连接请求,可以使用listen()函数来实现:
if (listen(server_socket, 3) < 0) { perror("listen failed"); close(server_socket); exit(EXIT_FAILURE); }
4、接受连接请求:当有客户端连接请求时,服务器需要接受这个请求,并创建一个新的套接字来与客户端通信,可以使用accept()函数来实现:
int addrlen = sizeof(address); int new_socket = accept(server_socket, (struct sockaddr *)&address, (socklen_t*)&addrlen); if (new_socket < 0) { perror("accept failed"); close(server_socket); exit(EXIT_FAILURE); }
5、处理数据传输:服务器端可以使用read()和write()函数来接收和发送数据,以下是一个简单的例子,服务器接收客户端发送的数据并回传给客户端:
char buffer[1024] = {0}; int valread = read(new_socket, buffer, 1024); printf("Received: %s ", buffer); write(new_socket, buffer, strlen(buffer));
客户端程序
1、创建套接字:客户端也需要创建一个套接字,使用方法与服务器端相同:
int client_socket = socket(AF_INET, SOCK_STREAM, 0); if (client_socket < 0) { perror("socket failed"); exit(EXIT_FAILURE); }
2、连接到服务器:客户端需要连接到指定的服务器IP地址和端口号,可以使用connect()函数来实现:
struct sockaddr_in serv_addr; serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(PORT); if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) { perror("Invalid address or address not supported"); close(client_socket); exit(EXIT_FAILURE); } if (connect(client_socket, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { perror("Connection failed"); close(client_socket); exit(EXIT_FAILURE); }
3、处理数据传输:客户端可以使用send()和recv()函数来发送和接收数据,以下是一个简单的例子,客户端发送数据到服务器并接收服务器的回传数据:
char *message = "Hello, Server!"; send(client_socket, message, strlen(message), 0); printf("Message sent "); char buffer[1024] = {0}; int valread = recv(client_socket, buffer, 1024, 0); printf("Received: %s ", buffer);
错误处理
在网络编程中,错误处理是非常重要的,需要确保在每个系统调用之后检查返回值,并在出现错误时进行适当的处理。
if (server_socket < 0) { perror("socket failed"); exit(EXIT_FAILURE); }
完整示例代码
服务器端代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #define PORT 8080 int main() { int server_fd, new_socket; struct sockaddr_in address; int opt = 1; int addrlen = sizeof(address); // Creating socket file descriptor if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("socket failed"); exit(EXIT_FAILURE); } // Forcefully attaching socket to the port 8080 if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) { perror("setsockopt"); exit(EXIT_FAILURE); } address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(PORT); // Forcefully attaching socket to the port 8080 if (bind(server_fd, (struct sockaddr *)&address, sizeof(address))<0) { perror("bind failed"); exit(EXIT_FAILURE); } if (listen(server_fd, 3) < 0) { perror("listen"); exit(EXIT_FAILURE); } if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen))<0) { perror("accept"); exit(EXIT_FAILURE); } char buffer[1024] = {0}; int valread = read(new_socket, buffer, 1024); printf("%s ",buffer); send(new_socket, buffer, strlen(buffer), 0); printf("Hello from server "); return 0; }
客户端代码
#include <stdio.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #define PORT 8080 int main() { int sock = 0; struct sockaddr_in serv_addr; char *hello = "Hello from client"; char buffer[1024] = {0}; if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf(" Socket creation error "); return -1; } serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(PORT); // Convert IPv4 and IPv6 addresses from text to binary form if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0) { printf(" Invalid address/ Address not supported "); return -1; } if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { printf(" Connection Failed "); return -1; } send(sock, hello, strlen(hello), 0); printf("Hello message sent "); valread = read(sock, buffer, 1024); printf("%s ",buffer); return 0; }
原创文章,作者:未希,如若转载,请注明出处:https://www.kdun.com/ask/1489936.html
本网站发布或转载的文章及图片均来自网络,其原创性以及文中表达的观点和判断不代表本网站。如有问题,请联系客服处理。
发表回复