August 17, 2023

Linux下使用Socket实现Tcp服务器的示例以及解释

Linux下使用Socket实现Tcp服务器 并不困难简略下来就的流程就一段

socket –> bind –> listen –> accept –> recv/send(处理数据) –> close

这就是Linux下实现服务器的流程,接下来我会给出代码并且逐步解析

这之中用到的函数都可以在这篇文章里看到解释

[ Linux下Socket编程中需要用到的函数以及结构体 ](https://zjhzzy.github.io/2023/08/15/Socket-
Programming-Functions-and-Structures-on-Linux/)

因为只是示例程序就 不进行错误判断 了,编写项目时还是需要错误判断的

示例代码

这段代码简单的实现了一个Tcp服务器,功能是接收对端发送来的消息并且输出,再将消息发送给对端

接下来简单的解释这些代码


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

|

#include <sys/socket.h>
#include <cstdio>
#include <arpa/inet.h>
#include <cstring>
#include <unistd.h>

int main() {
  int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  sockaddr_in addr = {0};
  addr.sin_addr.s_addr = INADDR_ANY;
  addr.sin_port = htons(8000);
  addr.sin_family = AF_INET;

  bind(sockfd, (sockaddr *)&addr, sizeof addr);

  listen(sockfd, 10);

  sockaddr_in clientAddr = {0};
  socklen_t clientAddrLen = sizeof clientAddr;
  int clientfd = accept(sockfd, (sockaddr *)&clientAddr, &clientAddrLen);
  while (true) {
	char buffer[1024] = {0};
	int recvByte = recv(clientfd, buffer, 1024, 0);
	if (recvByte <= 0) {
	  close(clientfd);
	  break;
	}
	printf("%s Say: %s", inet_ntoa(clientAddr.sin_addr), buffer);
	int sendByte = send(clientfd, buffer, 1024, 0);
	memset(buffer, 0, 1024);
	if (sendByte <= 0) {
	  close(clientfd);
	  break;
	}
  }
  close(sockfd);
}

—|—

声明一些需要的变量

向socket中传三个参数

AF_INET :使用 IPV4 地址族

SOCK_STREAM :流式套接字

IPPRORO_TCP :采用TCP协议

设置addr的值

因为是服务器所以将地址设置为 INADDR_ANY(0.0.0.0)

端口通过htons函数转换后赋值给sin_port

设置地址族为 AF_INET(IPV4)


1
2
3
4
5

|


int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
sockaddr_in addr = {0};
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(8000);
addr.sin_family = AF_INET;

—|—

绑定地址并启用监听(被动触发模式)


1
2

|


bind(sockfd, (sockaddr *)&addr, sizeof addr);
listen(sockfd, 10);

—|—

声明clientAddr去接收客户端的地址,accept返回套接字的文件描述符


1
2
3

|


sockaddr_in clientAddr = {0};
socklen_t clientAddrLen = sizeof clientAddr;
int clientfd = accept(sockfd, (sockaddr *)&clientAddr, &clientAddrLen);

—|—

声明buffer去接收客户端发送的数据,进行错误检查是否成功接收到数据,如果没有就关闭套接字


1
2
3
4
5
6

|


char buffer[1024] = {0};
int recvByte = recv(clientfd, buffer, 1024, 0);
if (recvByte <= 0) {
close(clientfd);
break;
}

—|—

输出对端发送来的数据,并将其发送给对端,使用memset清空buffer,进行错误检查是否成功发送数据,如果没有就关闭套接字


1
2
3
4
5
6
7

|


printf(“%s Say: %s”, inet_ntoa(clientAddr.sin_addr), buffer);
int sendByte = send(clientfd, buffer, 1024, 0);
memset(buffer, 0, 1024);
if (sendByte <= 0) {
close(clientfd);
break;
}

—|—

如果运行没有出错会输出一下消息


1
2

|


对端地址 Say: 对端发来的消息
对端地址 Say: 对端发来的消息

—|—

About this Post

This post is written by JinHong Zeng, licensed under CC BY-NC 4.0.

#C#Linux#Network