返回
Linux网络编程之socket详解:编写出色的通信软件
后端
2023-11-02 05:38:08
在计算机网络领域,socket函数是构建网络应用程序的基础。本文将详细介绍Linux网络编程之socket函数的用法,并以客户端和服务端间TCP通信的源码实现为例,详细讲解了socket函数的使用方法,同时还提供了端口状态监测的实现示例,帮助您更好地理解socket函数的应用。如果您想要编写出色的通信软件,本文将为您提供全面的指导。
1. socket函数讲解
socket函数是Linux系统中用于创建套接字的函数。套接字是应用程序之间进行通信的端点,它为应用程序提供了一种方法来发送和接收数据。socket函数的语法如下:
int socket(int domain, int type, int protocol);
其中,
domain
:指定套接字的域,常用的域有AF_INET
(IPv4)和AF_INET6
(IPv6)。type
:指定套接字的类型,常用的类型有SOCK_STREAM
(TCP)和SOCK_DGRAM
(UDP)。protocol
:指定套接字使用的协议,常用的协议有IPPROTO_TCP
(TCP)和IPPROTO_UDP
(UDP)。
2. 客户端和服务端间TCP通信的源码实现
在客户端和服务端间进行TCP通信时,需要使用socket函数来创建套接字,并使用connect()
函数和accept()
函数来建立连接。客户端使用connect()
函数连接到服务端的端口,服务端使用accept()
函数接受客户端的连接请求。连接建立后,客户端和服务端就可以通过套接字进行数据传输。
以下是如何使用socket函数实现客户端和服务端间TCP通信的源码:
// 服务端代码
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main()
{
int server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket == -1)
{
perror("socket");
return -1;
}
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8080);
server_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)
{
perror("bind");
return -1;
}
if (listen(server_socket, 10) == -1)
{
perror("listen");
return -1;
}
int client_socket = accept(server_socket, NULL, NULL);
if (client_socket == -1)
{
perror("accept");
return -1;
}
char buffer[1024];
while (1)
{
int recv_len = recv(client_socket, buffer, sizeof(buffer), 0);
if (recv_len == -1)
{
perror("recv");
return -1;
}
else if (recv_len == 0)
{
printf("Client disconnected.\n");
break;
}
printf("Received from client: %s", buffer);
int send_len = send(client_socket, buffer, recv_len, 0);
if (send_len == -1)
{
perror("send");
return -1;
}
}
close(client_socket);
close(server_socket);
return 0;
}
// 客户端代码
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main()
{
int client_socket = socket(AF_INET, SOCK_STREAM, 0);
if (client_socket == -1)
{
perror("socket");
return -1;
}
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8080);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(client_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)
{
perror("connect");
return -1;
}
char buffer[1024];
while (1)
{
printf("Enter a message to send: ");
scanf("%s", buffer);
int send_len = send(client_socket, buffer, strlen(buffer), 0);
if (send_len == -1)
{
perror("send");
return -1;
}
int recv_len = recv(client_socket, buffer, sizeof(buffer), 0);
if (recv_len == -1)
{
perror("recv");
return -1;
}
else if (recv_len == 0)
{
printf("Server disconnected.\n");
break;
}
printf("Received from server: %s", buffer);
}
close(client_socket);
return 0;
}
3. 单线程BIO实现
在Linux网络编程中,BIO(Blocking I/O)是一种常见的I/O模型。BIO模型采用阻塞式I/O操作,即当应用程序调用I/O函数时,应用程序会一直阻塞,直到I/O操作完成。
以下是如何使用BIO模型实现客户端和服务端间TCP通信的源码:
// 服务端代码
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main()
{
int server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket == -1)
{
perror("socket");
return -1;
}
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8080);
server_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)
{
perror("bind");
return -1;
}
if (listen(server_socket, 10) == -1)
{
perror("listen");
return -1;
}
int client_socket = accept(server_socket, NULL, NULL);
if (client_socket == -1)
{
perror("accept");
return -1;
}
char buffer[1024];
while (1)
{
int recv_len = recv(client_socket, buffer, sizeof(buffer), 0);
if (recv_len == -1)
{
perror("recv");
return -1;
}
else if (recv_len == 0)
{
printf("Client disconnected.\n");
break;
}
printf("Received from client: %s", buffer);
int send_len = send(client_socket, buffer, recv_len, 0);
if (send_len == -1)
{
perror("send");
return -1;
}
}
close(client_socket);
close(server_socket);
return 0;
}
// 客户端代码
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main()
{
int client_socket = socket(AF_INET, SOCK_STREAM, 0);
if (client_socket == -1)
{
perror("socket");
return -1;
}
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_