当前位置:网站首页>Complete TCP forwarding server (kernel linked list + mutex)
Complete TCP forwarding server (kernel linked list + mutex)
2022-06-30 14:06:00 【Fat Xiao Deng】
// The following code is for reference only , If there are any mistakes, please comment and correct , thank you !
// Server side
server.c
#include "myhead.h" // All required header files ( Except for the kernel linked list )
#include "kernel_list.h"// Kernel linked list header file
// Define a mutex
pthread_mutex_t m;
// Design client nodes
struct client
{
char ip[50]; // Save client ip
unsigned int port; // Save the client port
int connfd; // Save client connection socket
struct list_head list; // Define the kernel linked list
};
// Chain header node
struct client *head = NULL;
// Initializing the header node
struct client *list_init(void)
{
struct client *head = calloc(1, sizeof(struct client));
if(head == NULL)
{
perror("calloc failed");
exit(0);
}
INIT_LIST_HEAD(&head->list);
}
// single shot ( To the designated person )
bool send_single(char *msg, unsigned short port)
{
struct list_head *pos = NULL;
struct client *tmp = NULL;
// Lock shared resources
pthread_mutex_lock(&m);
list_for_each(pos, &head->list)
{
// find pos The first address of the structure type of the linked list node ,list yes struct client Structure member of type
tmp =list_entry(pos, struct client, list);
if(tmp->port == port)
{
write(tmp->connfd, msg, strlen(msg));
pthread_mutex_unlock(&m); // Abnormal situation , Unlock first , Quit again
return true;
}
}
pthread_mutex_unlock(&m); // The normal exit , Unlock
return false;
}
// Mass hair
void send_broadcast(char *msg, struct client* new)
{
struct list_head *pos = NULL;
struct client *tmp = NULL;
// Lock shared resources
pthread_mutex_lock(&m);
list_for_each(pos, &head->list)// Traverse the linked list from scratch ( During traversal , Nodes cannot be deleted )
{
tmp =list_entry(pos, struct client, list);
if(tmp->port != new->port)
{
write(tmp->connfd, msg, strlen(msg));
}
}
pthread_mutex_unlock(&m); // Unlock shared resources
}
// Client data receiving routine
void *recvclient(void *arg)
{
struct client *new = (struct client *)arg;
char msg[100];
char *str = NULL;
// Receive client data
while(1)
{
bzero(msg, 100);
read(new->connfd, msg, sizeof(msg));
printf(" come from [%s : %u] Customer service information : %s\n", new->ip, new->port,msg);
if(strncmp(msg, "quit", 4) == 0)// Client offline
{
printf("[%s : %u] The client is offline \n", new->ip, new->port);
close(new->connfd); // Close socket
list_del(&new->list); // Delete node from linked list
free(new); // Free up the requested space
break;
}
else if((str = strstr(msg, ":"))) // single shot // strstr:( Find the specified string in a string )
{
unsigned short port = atoi(msg);
if(!send_single(str+1, port))
{
printf(" This port was not found \n");
}
}
else // Mass hair
{
send_broadcast(msg, new);
}
}
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
if(argc != 2)
{
printf("usage: %s <PORT>\n", argv[0]);
exit(0);
}
// Initialize mutex
pthread_mutex_init(&m, NULL);
int sockfd = socket(AF_INET, SOCK_STREAM, 0);//TCP
if(sockfd == -1)
{
perror("sockfd faield");
exit(0);
}
struct sockaddr_in saddr, caddr;
bzero(&saddr, sizeof(saddr));
bzero(&caddr, sizeof(caddr));
saddr.sin_family = AF_INET; //Ipv4
saddr.sin_port = htons(atoi(argv[1]));
saddr.sin_addr.s_addr = htonl(INADDR_ANY);// Automatic access to IP
if(bind(sockfd, (struct sockaddr*)&saddr, sizeof(saddr)) == -1)
{
perror("bind faield");
exit(0);
}
// printf(" Binding success \n");
if(listen(sockfd, 5) == -1)
{
perror("listen faield");
exit(0);
}
printf(" Waiting for the connection \n");
// Initialize chain header
head = list_init(); //head After defining the structure, we define
socklen_t addrlen = (socklen_t)sizeof(caddr); //int len = sizeof(caddr);
int connfd;
// Waiting for multiple client connections
while(1)
{
if((connfd = accept(sockfd, (struct sockaddr*)&caddr, &addrlen)) == -1)
{
perror("accept faield");
exit(0);
}
printf("[%s : %u] Successful connection \n", inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port));
struct client *new = calloc(sizeof(struct client),1); // Apply for new node space
if(new == NULL)
{
perror("calloc Create nodes failed");
exit(0);
}
strcpy(new->ip, inet_ntoa(caddr.sin_addr));
new->port = ntohs(caddr.sin_port);
new->connfd = connfd;
// Managing shared resources —— Client linked list
pthread_mutex_lock(&m); // Lock
list_add_tail(&new->list, &head->list); // Insert the end of the list
pthread_mutex_unlock(&m); // Unlock
// Create thread , Receive client data
pthread_t tid;
pthread_create(&tid, NULL, recvclient, new);
}
return 0;
}
// The end of the service
client.c
#include "myhead.h"
// receive messages
void *Recv(void *arg)
{
int sockfd = *(int *)arg;
char msg[100];
while(1)
{
bzero(msg, 100);
read(sockfd, msg, 100);
printf("%s\n", msg);
}
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
if(argc != 3)
{
printf("usage: %s <IP> <PORT>\n", argv[0]);
exit(0);
}
// Create a socket
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd == -1)
{
perror("sockfd faield");
exit(0);
}
struct sockaddr_in saddr, caddr;
bzero(&saddr, sizeof(saddr));
bzero(&caddr, sizeof(caddr));
saddr.sin_family = AF_INET; //Ipv4
saddr.sin_port = htons(atoi(argv[2]));
// saddr.sin_addr.s_addr = htonl(INADDR_ANY);// Automatic access to IP
inet_pton(AF_INET, argv[1], &saddr.sin_addr);
connect(sockfd, (struct sockaddr*)&saddr, sizeof(saddr));
printf(" Successfully connected to the server \n");
pthread_t tid;
pthread_create(&tid, NULL, Recv, &sockfd);
// Send message buffer
char msg[100] = {
0};
while(1)
{
bzero(msg, 100);
printf(" Please enter the message to send :\n");fflush(NULL);
fgets(msg, 100, stdin);
write(sockfd, msg, strlen(msg));
if(strncmp(msg, "quit", 4) == 0)
{
printf(" sign out \n");
break;
}
}
close(sockfd);
return 0;
}
** Be careful :** Connection required during compilation -lpthread
边栏推荐
- Observable, reliable: the first shot of cloudops series Salon of cloud automation operation and maintenance
- 【系统分析师之路】第五章 复盘软件工程(软件过程改进)
- 这个编辑器即将开源!
- 目录相关命令
- 【 scientific literature measurement 】 mining and visualization of keywords in foreign and Chinese Literature
- [observation] as the intelligent industry accelerates, why should AI computing power take the lead?
- Introduction to reverse commissioning - VA and RVA conversion in PE 04/07
- Inexplicable error occurred in unity's frequent switching branch result model
- visualstudio 和sql
- [kubernetes series] k8s set mysql8 case insensitive
猜你喜欢

Google Earth Engine(GEE)——将字符串的转化为数字并且应用于时间搜索( ee.Date.fromYMD)

More than 20 years after Hong Kong's return, Tupu digital twin Hong Kong Zhuhai Macao Bridge has shocked

提权扫描工具

【科学文献计量】外文文献及中文文献关键词的挖掘与可视化

Tencent two sides: @bean and @component are used on the same class. What happens?

香港回归20余年,图扑数字孪生港珠澳大桥,超震撼

Intelligent operation and maintenance: visual management system based on BIM Technology

Waving flags and shouting for basic language
![[recruitment (Guangzhou)] Chenggong Yi (Guangzhou) Net core middle and Senior Development Engineer](/img/d8/a367c26b51d9dbaf53bf4fe2a13917.png)
[recruitment (Guangzhou)] Chenggong Yi (Guangzhou) Net core middle and Senior Development Engineer

navicat数据库建表是没有utf8选项。
随机推荐
A keepalived high availability accident made me learn it again!
Je suis à Foshan, où puis - je ouvrir un compte? L'ouverture d'un compte par téléphone mobile est - elle sécurisée?
一条查询SQL是如何执行的
Configuration of headquarters dual computer hot standby and branch infrastructure for firewall Foundation
我想问一下招商证券怎么开户?通过链接办理股票开户安全吗
IM即时通讯应用开发中无法解决的“顽疾”
Unity animator parameter
数字时代,XDR(扩展检测与响应)的无限可能
With the development of industrial Internet, the landing and application of the Internet has become wider
Deep understanding Net (2) kernel mode 4 Summary of kernel pattern constructs
Prometheus 2.29.0 新特性
Multi terminal collaboration of Huawei accounts to create a better internet life
[Title brushing] coco, who likes bananas
Data Lake (11): Iceberg table data organization and query
WTM major updates, multi tenancy and single sign on
深入理解.Net中的线程同步之构造模式(二)内核模式2.内核模式构造物Semaphone
Google Earth engine (GEE) -- converts string to number and applies it to time search (ee.date.fromymd)
这个编辑器即将开源!
Intelligent operation and maintenance: visual management system based on BIM Technology
Deep understanding Net (2) kernel mode 2 Kernel mode construct semaphone