当前位置: 首页 > news >正文

福州最好的网站建设服务商东莞seo软件

福州最好的网站建设服务商,东莞seo软件,河南省建设工程质监总站网站,什么是电商视觉设计概述 下面是一个通用的server端程序源码,用于实现两个client之间的通信。 功能 1、接收user的命令cmd消息,并将cmd消息发送到dev; 2、接收dev的应答ack消息,并将ack消息发送到user; 架构实现 通过6个线程实现。 …

概述

下面是一个通用的server端程序源码,用于实现两个client之间的通信。

功能

1、接收user的命令cmd消息,并将cmd消息发送到dev;

2、接收dev的应答ack消息,并将ack消息发送到user;

架构实现

通过6个线程实现。

thread_init_user

用于创建user socket,并创建接收user cmd的线程recv_cmd_from_user 和将ack发送给user的线程send_ack_to_user

recv_cmd_from_user

用于接收user客户端的cmd,并激活send_ack_to_user线程

send_ack_to_user

将user cmd发送到设备

thread_init_dev

用于创建dev socket,并创建将cmd发送给dev的线程send_cmd_to_dev 和接收dev ack的线程recv_ack_from_dev

send_cmd_to_dev

用于将user客户端的cmd 发送到dev客户端

recv_ack_from_dev

用于接收dev客户端的ack,并激活send_ack_to_user

注意要点

客户端断开后,server端相应的线程会收到长度为0的信息,收到此消息后,要退出这个线程,同时通知这个客户端的发送线程退出。

源码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <pthread.h>
#include <termios.h>
#include <string.h>
#include <dlfcn.h>
#include <sys/types.h>
#include <sys/time.h>
#include <dirent.h>
#include <signal.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <netinet/tcp.h>
#include <string.h>
#include <stdbool.h>
#include <linux/rtnetlink.h>
#include <netinet/ether.h>
#include <semaphore.h>#define FRAME_LEN_MAX 256static sem_t sem_recv_user;
static sem_t sem_send_dev;
static sem_t sem_recv_ack_start;
static sem_t sem_recv_ack_end;static unsigned char g_cmd_frame[FRAME_LEN_MAX];
static int g_cmd_frame_len;
static unsigned char g_ack_frame[FRAME_LEN_MAX];
static int g_ack_frame_len;static bool g_user_thread_exit;
static bool g_dev_thread_exit;static void *recv_cmd_from_user(void *arg)
{int fd = 0;int ret = 0;if (!arg) {printf("[%s] arg is NULL!\n", __FUNCTION__);return NULL;}fd = *(int *)arg;if (fd < 0) {printf("[%s] invailed arg!\n", __FUNCTION__);return NULL;}printf("[%s] thread run\n", __FUNCTION__);while (1) {ret = recv(fd, g_cmd_frame, FRAME_LEN_MAX, 0);printf("[%s] recv ret:%d!\n", __FUNCTION__, ret);if(ret <= 0) {//当用户客户端断开时,会走这里,本进程退出,同时发送信号量通知另个一线程退出g_user_thread_exit = 1;sem_post(&sem_recv_ack_start);break;}g_cmd_frame_len = ret;sem_post(&sem_recv_user);}close(fd);pthread_exit(NULL);
}static void *send_cmd_to_dev(void *arg)
{int fd = 0;int ret = 0;if (!arg) {printf("[%s] arg is NULL!\n", __FUNCTION__);return NULL;}fd = *(int *)arg;if (fd < 0) {printf("[%s] invailed arg!\n", __FUNCTION__);return NULL;}printf("[%s] thread run\n", __FUNCTION__);while (1) {sem_wait(&sem_recv_user);if(g_dev_thread_exit) {break;}ret = send(fd, g_cmd_frame, g_cmd_frame_len, 0);printf("[%s] send to client:%d ret:%d!\n", __FUNCTION__, fd, ret);if(ret <= 0) {break;}sem_post(&sem_send_dev);}close(fd);pthread_exit(NULL);
}static void *recv_ack_from_dev(void *arg)
{int fd = 0;int ret = 0;if (!arg) {printf("[%s] arg is NULL!\n", __FUNCTION__);return NULL;}fd = *(int *)arg;if (fd < 0) {printf("[%s] invailed arg!\n", __FUNCTION__);return NULL;}printf("[%s] thread run\n", __FUNCTION__);while (1) {sem_wait(&sem_send_dev);//dev客户端主动发送命令会被阻塞,直到user客户端发送命令sem_post(&sem_recv_ack_start);ret = recv(fd, g_ack_frame, FRAME_LEN_MAX);printf("[%s] recv ret:%d!\n", __FUNCTION__, ret);if(ret <= 0) {g_dev_thread_exit = 1;sem_post(&sem_recv_user);break;}g_ack_frame_len = ret;sem_post(&sem_recv_ack_end);}close(fd);pthread_exit(NULL);
}static void *send_ack_to_user(void *arg)
{int fd = 0;int ret = 0;if (!arg) {printf("[%s] arg is NULL!\n", __FUNCTION__);return NULL;}fd = *(int *)arg;if (fd < 0) {printf("[%s] invailed arg!\n", __FUNCTION__);return NULL;}printf("[%s] thread run\n", __FUNCTION__);while (1) {struct timespec ts;sem_wait(&sem_recv_ack_start);if(g_user_thread_exit) {break;}
#if 0//对应答时间有要求,可以打开这里if (clock_gettime(CLOCK_REALTIME, &ts) == -1)printf("[%s] ERROR:get current time failed\n",__FUNCTION__);ts.tv_nsec += 10 * MS_TO_NS;ret = sem_timedwait(&sem_recv_dev_end, &ts);
#elsesem_wait(&sem_recv_dev_end);
#endifret = send(fd, g_ack_frame, g_ack_frame_len);printf("[%s] send to client:%d ret:%d!\n", __FUNCTION__, fd, ret);if (ret <= 0) {break;}}close(fd);pthread_exit(NULL);
}void *thread_init_user(void *arg)
{struct sockaddr_in	server_addr;struct sockaddr_in  client_addr;pthread_t tid_rx;pthread_t tid_tx;int server_fd = 0;int client_fd = 0;int ret = 0;int addr_size = sizeof(client_addr);int port = *(int *)arg;server_fd = socket(AF_INET, SOCK_STREAM, 0);if(server_fd < 0){printf("[%s] socket failed! port:%d\n", __FUNCTION__, port);return NULL;}printf("[%s] socket sucess! server_fd:%d, port:%d\n", __FUNCTION__,server_fd, port);bzero( &server_addr, sizeof(struct sockaddr_in) );server_addr.sin_family		= AF_INET;server_addr.sin_addr.s_addr = inet_addr((const char*)IP_ADDR_DFLT);server_addr.sin_port		= htons(port);if(bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {printf("[%s] bind failed!\n", __FUNCTION__);return NULL;}printf("[%s] bind sucess! server_fd:%d\n", __FUNCTION__,server_fd);if (listen(server_fd, 10) == -1) {printf("[%s] listen failed!\n", __FUNCTION__);return NULL;}printf("[%s] listen sucess! server_fd:%d\n\n", __FUNCTION__,server_fd);set_socket_alive(server_fd);while (server_fd != -1) {client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &addr_size);if (client_fd < 0) {printf("[%s] accept failed: %d!\n", __FUNCTION__, client_fd);sleep(1);continue;}g_user_thread_exit = 0;printf("[%s] client: %d connected!\n", __FUNCTION__, client_fd);ret = pthread_create(&tid_rx, NULL, recv_cmd_from_user, &client_fd);if(ret != 0) {continue;}pthread_detach(tid_rx);ret = pthread_create(&tid_tx, NULL, send_ack_to_user, &client_fd);if(ret != 0) {continue;}pthread_detach(tid_tx);}return NULL;
}void *thread_init_dev(void *arg)
{struct sockaddr_in	server_addr;struct sockaddr_in  client_addr;pthread_t tid_rx;pthread_t tid_tx;int server_fd = 0;int client_fd = 0;int ret = 0;int addr_size = sizeof(client_addr);int port = *(int *)arg;server_fd = socket(AF_INET, SOCK_STREAM, 0);if(server_fd < 0){printf("[%s] socket failed!\n", __FUNCTION__);return NULL;}printf("[%s] socket sucess! server_fd:%d, port:%d\n", __FUNCTION__,server_fd, port);bzero( &server_addr, sizeof(struct sockaddr_in) );server_addr.sin_family		= AF_INET;server_addr.sin_addr.s_addr = inet_addr((const char*)IP_ADDR_DFLT);server_addr.sin_port		= htons(port);if(bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {printf("[%s] bind failed!\n", __FUNCTION__);return NULL;}printf("[%s] bind sucess! server_fd:%d\n", __FUNCTION__,server_fd);if (listen(server_fd, 10) == -1) {printf("[%s] listen failed!\n", __FUNCTION__);return NULL;}printf("[%s] listen sucess! server_fd:%d\n\n", __FUNCTION__,server_fd);set_socket_alive(server_fd);while (server_fd != -1) {client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &addr_size);if (client_fd < 0) {printf("[%s] accept failed: %d!\n", __FUNCTION__, client_fd);sleep(1);continue;}g_dev_thread_exit = 0;printf("[%s] client: %d connected!\n", __FUNCTION__, client_fd);ret = pthread_create(&tid_rx, NULL, recv_ack_from_dev, &client_fd);if(ret != 0) {continue;}pthread_detach(tid_rx);ret = pthread_create(&tid_tx, NULL, send_cmd_to_dev, &client_fd);if(ret != 0) {continue;}pthread_detach(tid_tx);}return NULL;
}int main(int argc, char *argv[])
{int user_port = PORT_USER;int dev_port = PORT_DEV;pthread_t thread_user;pthread_t thread_dev;pthread_attr_t attr;if(argc >= 2)user_port = auto_convert_0x(argv[1]);if(argc >= 3)dev_port = auto_convert_0x(argv[2]);printf("[%s]user_port:%d, dev_port:%d\n", __FUNCTION__, user_port, dev_port);sem_init(&sem_recv_user,0,0);sem_init(&sem_send_dev,0,0);sem_init(&sem_recv_ack_start,0,0);sem_init(&sem_recv_ack_end,0,0);pthread_attr_init (&attr);pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);if (0 != pthread_create(&thread_user, &attr, thread_init_user, (void *)&user_port)) {printf("[%s] thread_user init failed\n", __FUNCTION__);return 0;}sleep(1);if (0 != pthread_create(&thread_dev, &attr, thread_init_dev, (void *)&dev_port)) {printf("[%s] thread_dev init failed\n", __FUNCTION__);return 0;}while(1) {sleep(UINT32_MAX);}return 0;
}

参考文档

linux下的Socket网络编程教程_linux socket 编程示例-CSDN博客

http://www.dinnco.com/news/33375.html

相关文章:

  • 深圳市建设设计院网站关键词搜索神器
  • 网页设计师都在什么网站上面找素材深圳百度关键词排名
  • 开发次元世界重庆seo网站排名
  • 做外贸都用什么网站百度一下你就知道官网
  • 天津 企业网站建设口碑营销的重要性
  • 外贸网站平台排名百度竞价平台官网
  • html5单页模板五年级上册语文优化设计答案
  • 网站建设方法网络优化工作应该怎么做
  • 设计师网站导航今日发生的重大国际新闻
  • 做调查问卷的网站有什么seo 推广怎么做
  • 怎么建立网站管理系统2345网址大全设主页
  • 台州网站制作 外贸软件网站排行榜
  • 手机网站的域名网络营销渠道有哪几种
  • 怎么做谷歌收录的网站seo企业顾问
  • 织梦做的网站别人提交给我留的言我去哪里看seo自媒体培训
  • 电子商务网站建设 实验分析免费顶级域名申请网站
  • 深圳有做网站最近价格百度推广官网电话
  • 互联网+中央督查关键词优化的主要工具
  • 网站建设与推广的步骤推广平台都有哪些
  • 手机老是下载一些做任务的网站谷歌海外推广怎么做
  • 做网站是靠什么赚钱的成都搜索优化排名公司
  • win8式网站后台模板成都seo招聘
  • 新手怎么做自己网站广告谷歌seo工具
  • 四川做网站的公司哪家好辽宁网站seo
  • 网站运营需要 做哪些工作内容品牌策略
  • 网站建设 系统维护企业网站建设的作用
  • 做建材商城网站互联网营销师培训教材
  • 西安建委官网百度关键词优化服务
  • 如何免费制作网站seo资料
  • 营销型网站建设案例分析全球搜索引擎排名