php多线程tcp,Linux 下tcp多线程编程-程序员宅基地

技术标签: php多线程tcp  

/* 服务器端server程序 */

/* 编译命令:gcc -Wall -g -o server server.c -lpthread */

#include #include #include #include #include #include #include #include #include #include

#define PORT 8458

#define MAX_LISTEN 20

typedef struct MsgHead{

unsigned char type;

unsigned char BL[4];

}MH;

pthread_mutex_t mutex;

pthread_attr_t attr;

char *get_time_string(char *sbuf)

{

time_t Now;

struct tm *tm;

struct tm temp_time;

time (&Now);

tm = localtime_r(&Now, &temp_time);

sprintf(sbuf, "%.4d%.2d%.2d_%.2d%.2d%.2d",

tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,

tm->tm_hour, tm->tm_min, tm->tm_sec);

return sbuf;

}

char *GetFileName(char *filename)

{

char strTime[20];

char strFileName[64];

memset(strTime,0x00,sizeof(strTime));

memset(strFileName,0x00,sizeof(strFileName));

sleep(1);

get_time_string(strTime);

strcpy(strFileName,"rec_");

strcat(strFileName,strTime);

strcat(strFileName,".dat");

strcpy(filename,strFileName);

return filename;

}

int tcp_recv(int fd,int len, char *strRecv)

{

char *p = strRecv;

int iRet = -1,iRecvLen = -1,count = 0;

fd_set rset;

struct timeval tv;

tv.tv_sec = 0;

tv.tv_usec = 0;

while(len > 0)

{

FD_ZERO(&rset);

FD_SET(fd,&rset);

iRet = select (fd+1,&rset,NULL,NULL,&tv);

//printf("iRet = %d\n",iRet);

if (iRet < 0)

{

printf("tcp select error:%s\n",strerror(errno));

break;

}

else if (iRet == 0)

{

sleep(1);

continue;

}

iRecvLen = recv(fd,p,len,0);

if (iRecvLen > 0)

{

len -= iRecvLen;

p += iRecvLen;

count += iRecvLen;

}

}

return count;

}

void *recv_msg(void *clfd)

{

MH *MsgHead = NULL;

int iMHL,iBodyLen,iRet = -1,iType = -1,iRecCount = 0;

char RecvBuf[1024] = {"\0"},sFileName[64] = {"\0"};

int fd = *((int *)clfd);

FILE *fp = NULL;

printf("clfd=%d\n",fd);

iMHL = sizeof(MH);

/* 打开一个文件用于存放sql 语句 */

pthread_mutex_lock(&mutex);

GetFileName(sFileName);

pthread_mutex_unlock(&mutex);

printf("Filename:%s\n",sFileName);

if ( 0 > strlen(sFileName))

{

printf("get filename failed\n");

return NULL;

}

fp = fopen(sFileName,"w+");

if (!fp)

{

printf("open file %s failed: %s\n",sFileName,strerror(errno));

return NULL;

}

fprintf(fp,"%s\n","set termout on");

fprintf(fp,"%s\n","set feed off");

while(1)

{

memset(RecvBuf,0X00,sizeof(RecvBuf));

//Get message head

iRet = tcp_recv(fd,iMHL,RecvBuf);

if (iRet != iMHL)

{

printf("get msg head failed !\n");

continue;

}

iBodyLen = 0;

MsgHead = (MH *)RecvBuf;

iType = (int)MsgHead->type;

//printf("type :%d\n",iType);

if (2 == iType)

{

printf("\nServer tell:client %d exit!\n\n",fd);

//sleep(10);

fprintf(fp,"%s\n","commit;");

fclose(fp);

close(fd);

return 0;

}

iBodyLen += MsgHead->BL[0] * 256 * 256 * 256;

iBodyLen += MsgHead->BL[1] * 256 * 256;

iBodyLen += MsgHead->BL[2] * 256;

iBodyLen += MsgHead->BL[3];

//printf("BodyLen=%d\n",iBodyLen);

memset(RecvBuf,0X00,sizeof(RecvBuf));

iRet = tcp_recv(fd,iBodyLen,RecvBuf);

if (iRet == iBodyLen)

{

RecvBuf[iBodyLen] = '\0';

if (1000 > iRecCount)

{

fprintf(fp,"%s\n",RecvBuf);

iRecCount++;

}

else

{

/* 本文件已写满1000 条记录 */

fprintf(fp,"%s\n","commit;");

fclose(fp);

/* 重新打开一个文件写记录 */

iRecCount = 0;

memset(sFileName,0x00,sizeof(sFileName));

pthread_mutex_lock(&mutex);

GetFileName(sFileName);

pthread_mutex_unlock(&mutex);

printf("Filename:%s\n",sFileName);

if ( 0 > strlen(sFileName))

{

printf("get filename failed\n");

return NULL;

}

fp = fopen(sFileName,"w+");

fprintf(fp,"%s\n","set termout on");

fprintf(fp,"%s\n","set feed off");

fprintf(fp,"%s\n",RecvBuf);

iRecCount++;

}

}

}

return 0;

}

void sig_handler(int signo)

{

switch (signo)

{

case SIGTERM:

case SIGINT:

printf("received SIGTERM or SIGINT(tid:%u)", (unsigned int)pthread_self());

break;

case SIGHUP:

printf("received SIGHUP(tid:%u)", (unsigned int)pthread_self());

break;

case SIGUSR1:

printf("received SIGUSR1(tid:%u)", (unsigned int)pthread_self());

break;

case SIGPIPE:

printf("received SIGPIPE(tid:%u)", (unsigned int)pthread_self());

break;

default:

printf("received signal %d(tid:%u)", signo, (unsigned int)pthread_self());

break;

}

}

int setup_sig_handlers(void)

{

struct sigaction act;

act.sa_handler = sig_handler;

sigemptyset(&act.sa_mask);

act.sa_flags = 0;

sigaction(SIGTERM,&act,NULL);

sigaction(SIGINT, &act, NULL);

sigaction(SIGHUP, &act, NULL);

sigaction(SIGUSR1,&act,NULL);

sigaction(SIGUSR2,&act,NULL);

sigaction(SIGPIPE, &act, NULL);

return 0;

}

int main()

{

struct sockaddr_in SerAddr,CliAddr;

int serfd = -1,clfd = -1,iSize = -1,count = 0;

int bufSize = 4 * 1024 * 1024;

pthread_t tid[256];

pthread_attr_init(&attr);

pthread_mutex_init(&mutex,NULL);

pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);

setup_sig_handlers();

iSize = sizeof(SerAddr);

serfd = socket(PF_INET,SOCK_STREAM,0);

if (0 > serfd)

{

printf("init socket failed:%d\n",serfd);

return 0;

}

memset(&(SerAddr),0x00,sizeof(struct sockaddr_in));

memset(&(CliAddr),0x00,sizeof(struct sockaddr_in));

SerAddr.sin_family = AF_INET;

SerAddr.sin_port = htons(PORT);

SerAddr.sin_addr.s_addr = htonl(INADDR_ANY);

if ( 0  > bind(serfd,(struct sockaddr *)&SerAddr,iSize))

{

printf("server bind  to port %d failed \n",PORT);

return 0;

}

if ( 0 > setsockopt(serfd,SOL_SOCKET,SO_RCVBUF,&bufSize,sizeof(bufSize)))

{

printf("setsockopt error:%s",strerror(errno));

return -1;

}

if (0 > listen(serfd,MAX_LISTEN))

{

printf("listen failed\n");

return 0;

}

while(1)

{

clfd = accept(serfd,(struct sockaddr *)&CliAddr,&iSize);

if (0 > clfd)

{

printf("accept failed %s",strerror(errno));

sleep(1);

continue;

}

if (count < 256)

{

pthread_create(&tid[count++],&attr,recv_msg,(void *)&clfd);

}

else

{

printf("\n\ntoo many threads \n\n");

return - 1;

}

}

pthread_mutex_destroy(&mutex);

pthread_attr_destroy(&attr);

return 0;

}

/* 客户端 */

/* 编译命令  gcc -Wall -g -o client client.c */

#include #include #include #include #include #include #include #include #include #include #include

typedef struct MsgHead{

unsigned char type;

unsigned char BL[4];

}MH;

int con_serv()

{

struct sockaddr_in SerAddr;

int tcpfd = -1,iPort = 8458,iCount = 0;

char sIP[64] = {"\0"};

int sndBufSize = 4 * 1024 * 1024;

tcpfd = socket(AF_INET,SOCK_STREAM,0);

if(tcpfd < 0)

{

printf("socket error:%s\n",strerror(errno));

return -1;

}

if ( 0 > setsockopt(tcpfd, SOL_SOCKET, SO_SNDBUF, (char *)&sndBufSize, sizeof(sndBufSize)))

{

printf("make_tcp(): setsockopt failed for server address\n");

return -1;

}

memset(&(SerAddr),0x00,sizeof(SerAddr));

memset(sIP,0x00,sizeof(sIP));

strcpy(sIP,"127.0.0.1");

SerAddr.sin_family = AF_INET;

SerAddr.sin_port = htons(iPort);

SerAddr.sin_addr.s_addr = inet_addr(sIP);

for (iCount = 0; iCount < 3; iCount++)

{

if (0 > connect(tcpfd,(struct sockaddr *)&SerAddr,sizeof(struct sockaddr)))

{

printf("the %d times connect to machine: %s,port:%d failed \n",iCount + 1,sIP,iPort);

}

else

{

return tcpfd;

}

}

return -1;

}

void tcp_send(int tcpfd,int num)

{

fd_set wset;

struct timeval tv = {1,0};

int i = 0,iRet = -1;

char buf[128] = {"\0"},*p = NULL;

char Msg[1024] = {"\0"};

int iLen = 128;

MH MsgHead,*MsHe = NULL;

for (i = 0; i < num; i++)

{

memset(Msg,0x00,sizeof(Msg));

memset(buf,0x00,sizeof(buf));

p = Msg;

//sleep(1);

sprintf(buf,"string%d-string%d-string%d-string%d-string%d",i + 1,i + 1,i + 1,i + 1,i + 1);

MsgHead.BL[0] = (unsigned char)(strlen(buf) / 256 /256 /256);

MsgHead.BL[1] = (unsigned char)(strlen(buf) / 256 /256 );

MsgHead.BL[2] = (unsigned char)(strlen(buf) / 256 );

MsgHead.BL[3] = (unsigned char)(strlen(buf) % 256 );

MsgHead.type = (unsigned char)0;

memcpy(p,&MsgHead,sizeof(MH));

p = p + sizeof(MH);

memcpy(p,buf,strlen(buf));

p = NULL;

iLen = sizeof(MH) + strlen(buf);

while(iLen > 0)

{

FD_ZERO(&wset);

FD_SET(tcpfd,&wset);

iRet = select(tcpfd + 1,NULL,&wset,NULL,&tv);

if ( 0 > iRet)

{

printf("select error%s  reconnect\n",strerror(errno));

close(tcpfd);

sleep(1);

tcpfd = con_serv();

continue ;

}

else if ( 0 == iRet)

{

continue;

}

else

{

iRet = send(tcpfd,Msg,iLen,0);

if ( 0 > iRet )

{

printf("send failed\n");

}

else

{

iLen -= iRet;

}

}

}

}

printf("tcpfd:%d already send %d record,",tcpfd,num);

printf("send diconnect request\n");

MsHe = (MH *)Msg;

memset(Msg,0x00,sizeof(Msg));

MsHe->BL[0] = (unsigned char)0;

MsHe->BL[1] = (unsigned char)0;

MsHe->BL[2] = (unsigned char)0;

MsHe->BL[3] = (unsigned char)0;

MsHe->type = (unsigned char)2;

iLen = sizeof(MH);

iRet = send(tcpfd,Msg,iLen,0);

if ( iRet != iLen)

{

printf("send failed\n");

}

return;

}

void *execute(void *num)

{

int tcpfd = -1;

int number = *((int *)num);

printf("pthread_id = %u\n",(unsigned int)pthread_self());

tcpfd = con_serv();

if ( 0 < tcpfd )

{

tcp_send(tcpfd,number);

}

else

{

printf("connect to server failed!\n");

return NULL;

}

//sleep(10);

close(tcpfd);

printf("\nclient exit!\n\n");

return NULL;

}

int  main(int argc,char **argv)

{

int num = 0,i = 0,sendrec = 0;

pthread_t tid;

if (argc == 1)

{

num = 5;

}

else

{

for (i = 0; i < strlen(argv[1]); i++)

{

if (!isdigit(argv[1][i]))

{

printf("please added a number string\n!");

return 0;

}

}

num = atoi(argv[1]);

if (0 >= num || 65536 < num)

{

num = 5;

}

}

printf("send %d record\n",num);

sendrec = num;

for (i = 0; i < 5; i++)

{

sendrec *= (i + 1);

pthread_create(&tid,NULL,execute,(void *)&sendrec);

sleep(1);

sendrec = num;

}

for (i = 0; i < 5; i++)

{

pthread_join(tid,NULL);

}

return 0;

}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_42510768/article/details/116073982

智能推荐

飞行管理数学建模论文_飞机的安全飞行管理调度问题1995年csdn-程序员宅基地

文章浏览阅读6.7k次,点赞13次,收藏95次。飞行管理问题建模目录(1)摘要(2)问题重述(3)问题分析(4)模型假设(5)符号说明(6)模型的建立与求解(7) 模型的缺点与改进方向摘要对飞行区域内的飞机,通过调整飞机飞行的角度且飞机调整的幅度要尽量小来避免飞机相撞的的问题,本文先将区域内任意两架飞机在区域内飞行时不相撞的条件转化成关于飞机在飞行区域内关于飞行时间的非线性约束条件,即任意两架飞机在未飞出区域的时间里,..._飞机的安全飞行管理调度问题1995年csdn

大作业毕设系列基于matlab的直方图优化的图像去雾系统_基于matlab的图像去雾系统毕业设计-程序员宅基地

文章浏览阅读377次。雾霾天气往往会给人类的生产和生活带来极大不便,也大大增加了交通事故的发生概率。一般而言,在恶劣天气(如雾天、雨天等)条件下,户外景物图像的对比度和颜色会被改变或退化,图像中蕴含的许多特征也会被覆盖或模糊,这会导致某些视觉系统(如电子卡口、门禁监控等)无法正常工作。因此,从在雾霾天气下采集的退化图像中复原和增强景物的细节信息具有重要的现实意义。数字图像处理技术已被广泛应用于科学和工程领域,如地形分类系统、户外监控系统、自动导航系统等。为了保证视觉系统全天候正常工作,就必须使视觉系统适应各种天气状况。_基于matlab的图像去雾系统毕业设计

IDEA Help–>Edit Custom VM Options 修改后导致打不开进行复原-程序员宅基地

文章浏览阅读1.2k次。IDEA Help–>Edit Custom VM Options 修改后的坑_edit custom vm options

LVGL之GUI GUIder使用教程_lvgl界面编辑器-程序员宅基地

文章浏览阅读3.6k次,点赞7次,收藏28次。lvgl是一个免费的开放源代码图形库,提供创建具有易于使用的图形元素,再配合NXP提供的GUI-Guider软件,极大简化了嵌入式系统UI的设计。GUI Guider是恩智浦提供的用户友好型图形用户界面开发工具,可通过开源LVGL图形库快速开发高品质的显示。GUI Guider的拖放编辑器可以轻松利用LVGL的众多特性,如小部件、动画和样式来创建GUI,而只需少量代码或根本无需任何代码。单击按钮,您可以在模拟环境中运行应用或将其导出到目标项目。_lvgl界面编辑器

Unity Editor 不同枚举显示不同属性_unity 面板中不同枚举选择不同属性-程序员宅基地

文章浏览阅读623次。1_unity 面板中不同枚举选择不同属性

基于ffmpeg的MP4文件解封装_linux ffmpegmp4解封装-程序员宅基地

文章浏览阅读944次,点赞26次,收藏14次。基于ffmpeg的MP4文件解封装_linux ffmpegmp4解封装

随便推点

极客公园对话 Zilliz 星爵:大模型时代,需要新的「存储基建」-程序员宅基地

文章浏览阅读563次。大模型在以「日更」进展的同时,不知不觉也带来一股焦虑情绪:估值 130 亿美元的 AI 写作工具 Grammarly 在 ChatGPT 发布后网站用户直线下降;AI 聊天机器人独角兽公司 Character.AI 的自建大模型在 ChatGPT 进步之下,被质疑能否形成足够的竞争壁垒 …ChatGPT Plugins 插件发布之后,更多创业者开始担忧大模型的技术进步会把自己卷入「打击射程」,瞬时抹掉自己所在领域的技术积累和优势。

桌面被关闭,如何在任务管理器中打开桌面?_任务管理器打开桌面-程序员宅基地

文章浏览阅读3.8w次,点赞15次,收藏9次。explorer.exe就是windows系统的资源管理器主程序,也是桌面显示程序。如果要在任务管理器中打开桌面方法如下:1、打开任务管理器。2、点击菜单栏文件。3、新建任务,然后输入explorer按确定即可。..._任务管理器打开桌面

虚拟化 (Hypervisor) 技术详解-程序员宅基地

文章浏览阅读1.5k次,点赞34次,收藏24次。随着 ICT 技术的发展,单 SOC 算力可以承担更多业务,网络带宽拓展及低时延、区分服务等特性使得业务部署、功能分配更加灵活,比如 : 感知、融合、规划、控制、执行可分离解耦,汽车业务功能可分可合、可软件定义。电子电气架构从分布式架构到域集中式架构,再到中央集中式架构转变,分散的 ECU功能集成到域控制器甚至车载中央计算机,这就是多域融合。汽车电子底层硬件不再是由单一芯片提供简单的逻辑计算,而是需要复杂的多核 SoC 芯片提供更为复杂控制逻辑以及强大的算力支持。但是多域业务具有不同的技术需求,在域融合的同_hypervisor

html margin不居中,html中使用margin:0 auto整个页面不居中的解决方法分享-程序员宅基地

文章浏览阅读460次。今天写个jsp页面,乍么调来调去123xxx 这个属怎么弄都不能让页面居中展示,而且其它样式也出现莫名其妙的问题后来找这个这个问题的解决方案:原来是L-Blog默认没有在HTML前加上DTD,于是IE就以HTML而不是XHTML来解释文档.问题并不在CSS而在XHTML网页本身.需要加上这样的代码才能使得上述设置有效果:复制代码代码如下:-//W3C//DTD XHTML 1.0 Transiti..._html导入jsp不居中

【学习笔记】Esp32 Arduino 串口中断函数 缓冲区修改_arduino setrxfifofull-程序员宅基地

文章浏览阅读3.3k次,点赞8次,收藏32次。Esp32在Arduino开发环境下的串口中断实现和串口接收大数据的处理办法(修改缓冲区大小)_arduino setrxfifofull

Apache Tomcat 问题漏洞_apache tomcat 安全漏洞(cve-2023-28709)-程序员宅基地

文章浏览阅读1.1k次。Apache Tomcat 环境问题漏洞(CVE-2022-42252)Apache Tomcat 信息泄露漏洞(CVE-2023-28708)建议直接升级tomcat的小版本,即就是升级到最新版本注:跨版本升级请自行百度。_apache tomcat 安全漏洞(cve-2023-28709)