- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在多线程环境中开发客户端-服务器应用程序。客户端和服务器都有两个线程。主线程使用套接字(IPv4-TCP)发送数据,客户端相应的主线程接收数据发送和接收函数是自定义函数,作为我设计的一部分。我在另一个线程中为服务器上的 SIGUSR1、SIGUSR2 和 SIGINT 设置了三个信号处理程序。在接收 SIGINT 时,会进行线程清理以正常关闭所有套接字并终止线程,而在接收 SIGUSR1,SIGUSR2 时,我设置了两个全局标志,它们在同一线程中使用,并在主线程中的自定义发送函数中执行一些操作将套接字id切换到IPv6的操作。(有逻辑让客户端知道套接字已更改为IPv6)。自定义发送/接收函数有 malloc 和 free 函数。
问题是当我在终端上使用kill -SIGUSR1 pid向服务器进程发送信号时,在一些发送调用之后,传输挂起。对于每个发送调用,我正在发送数据包,该数据包具有要发送的数据大小,实际数据和一个可选标志,指示下一个数据将位于另一个套接字 ID 上。当我在客户端打印数据大小时,在收到信号后进行某些recv调用后,数据大小全为零。我确信信号必须是原因,因为当我反转操作并让客户端将数据发送到服务器(上传)时使用相同的发送/接收功能,它工作正常。我可以切换套接字 ID。在这两种情况下,我都会向服务器进程发送信号。由于 TCP 是基于流的,因此 recv 函数会一直接收数据,直到数据量与该数据包的大小部分中指示的相同。我不确定为什么在接收信号时进行一些发送调用后大小会变为零。我在使用全局变量的地方使用了互斥体,除了在设置信号处理程序部分时。代码如下。
主题 2:
fn_sigUsrHandler(SIGUSR1);
fn_sigUsrHandler(SIGUSR2);
fn_sigUsrHandler(SIGINT);
void fn_sigUsrHandler(int p_signal)
{
/* Signal handler structure */
struct sigaction vl_sigStruct;
int vl_errno;
char vl_err_buff[256];
vl_sigStruct.sa_flags = SA_RESTART;
sigemptyset(&vl_sigStruct.sa_mask);
switch(p_signal)
{
case SIGUSR1:
vl_sigStruct.sa_handler = fn_switch;
break;
case SIGUSR2:
vl_sigStruct.sa_handler = fn_switch;
break;
case SIGINT:
vl_sigStruct.sa_handler = fn_cleanUP;
break;
}
vl_errno = sigaction(p_signal, &vl_sigStruct, NULL);
if (vl_errno == -1) {
fprintf(stdout,"Control Thread-Error in catching SIGUSR1:%s\n",fn_strerror_r(errno,vl_err_buff));
exit(EXIT_FAILURE);
}
void fn_switch(int st_val){
/*
pthread_mutex_lock(&socket_mutex_3);
ip_proto_switch = 1;
vg_ctrlpacket_sent =1;
pthread_mutex_unlock(&socket_mutex_3);
*/
vg_proto_switch = 1;
vg_ctrlpacket_sent =1;
fprintf(stdout,"Signalled to switch\n");
}
主线程:
int vl_err; /* Number of bytes sents */
char err_buff[256]; /* Buffer to hold error message*/
int vl_change_sock = 0;
if(p_flags != NO_DATA_TX)
{
char *vl_bufData;
st_packetData vst_packet; /* Structure holding the data to be sent */
unsigned int vl_packetSize = sizeof(unsigned int) + sizeof(vst_packet.vst_pad) + (int)p_len;//sss
vl_bufData = (char *)malloc(vl_packetSize);
memset(vl_bufData,'\0',vl_packetSize);
pthread_mutex_lock(&socket_mutex_2);
if(vg_ctrlpacket_recv == 1){
///strcpy(vst_packet.vst_pad,vg_change_socket);
vl_change_sock = 1;
vg_ctrlpacket_recv = 0;
fprintf(stdout,"len:%d\n",strlen(vst_packet.vst_pad));
}
pthread_mutex_unlock(&socket_mutex_2);
if(vl_change_sock == 1){
char *vl_bufData2 = vl_bufData+sizeof(unsigned int);
snprintf(vl_bufData2,(int)p_len,"%s",p_buffer);
//memcpy(vl_bufData+sizeof(unsigned int)+(int)p_len,vg_change_socket,sizeof(vst_packet.vst_pad));//sss
*/
snprintf(vl_bufData,sizeof(unsigned int)+1,"%u",vl_packetSize);
memcpy(vl_bufData+sizeof(unsigned int),p_buffer,(int)p_len);//sss
snprintf(vl_bufData+sizeof(unsigned int)+(int)p_len,sizeof(vst_packet.vst_pad)+1,"%s",vg_change_socket);
vl_err = send(p_mysocket->socket_id,vl_bufData,vl_packetSize,p_flags);
if(vl_err == -1)
{
fprintf(stderr,"mysocket-fn_send-TCP-vl_err err :%s\n",fn_strerror_r(errno,err_buff));//HS
exit(EXIT_FAILURE);//HS
}
if(debug > 0)
fprintf(stdout,"The socket before change is :%d client side \n",p_mysocket->socket_id);
if((p_mysocket->socket_id) == p_mysocket->sock_id[0])
p_mysocket->socket_id = p_mysocket->sock_id[1];
else
p_mysocket->socket_id = p_mysocket->sock_id[0];
if(debug > 0)
fprintf(stdout,"The socket after change is :%d client side \n ",p_mysocket->socket_id);
}
else{
snprintf(vl_bufData,sizeof(unsigned int)+1,"%u",vl_packetSize);
memcpy(vl_bufData+sizeof(unsigned int),p_buffer,(int)p_len);//sss
vl_err = send(p_mysocket->socket_id,vl_bufData,vl_packetSize,p_flags);
if(vl_err == -1)
{
fprintf(stderr,"mysocket-fn_send-TCP-vl_err err :%s\n",fn_strerror_r(errno,err_buff));//HS
exit(EXIT_FAILURE);//HS
}
}
if(debug > 2){
/*fprintf(stdout,"size of st_packetData:%d\n",sizeof(st_packetData));
fprintf(stdout,"vl_packetSize:%d\n",vl_packetSize);
fprintf(stdout,"Memcopied-data:%s\n",vst_packet.vst_data);
fprintf(stdout,"Memcopied-pad:%s\n",vst_packet.vst_pad);
fprintf(stdout,"Memcopied-size:%d\n",vst_packet.vst_size);//sss
fprintf(stdout,"Data from buffer:%s\n",p_buffer);
fprintf(stdout,"data:%s\n",vl_bufData+sizeof(vst_packet.vst_size)+sizeof(vst_packet.vst_pad));*/
fprintf(stdout,"Copied data:%-10.6s\n",vl_bufData);
fprintf(stdout,"---------------------------\n");
}
//if(vl_err >=(sizeof(vst_packet.vst_size)+ sizeof(vst_packet.vst_pad))) //sss
if(vl_err >=(sizeof(unsigned int)+ strlen(vg_change_socket)))
{
vl_err = vl_err-(sizeof(unsigned int) + strlen(vg_change_socket));//sss
}
if(debug > 2)
{
fprintf(stdout,"The socket id is :%d.. Thread:%s\n",p_mysocket->socket_id,p_mysocket->vst_nm_thread);
fprintf(stdout,"The data tx %d.. Thread:%s\n",vl_err,p_mysocket->vst_nm_thread);
}
free((void *)vl_bufData);
}
else
{
vl_err = send(p_mysocket->socket_id,p_buffer,p_len,0);
if(vl_err == -1)
{
fprintf(stderr,"mysocket-fn_send-TCP-vl_err err :%s\n",fn_strerror_r(errno,err_buff));//HS
exit(EXIT_FAILURE);//HS
}
if(debug>1)
{
fprintf(stdout,"The socket id is :%d.. Thread:%s\n",p_mysocket->socket_id,p_mysocket->vst_nm_thread);
fprintf(stdout,"The data tx %d.. Thread:%s\n",vl_err,p_mysocket->vst_nm_thread);
}
}
/* return number of bytes sent */
return vl_err;
}
最佳答案
感谢大家的回复。经过进一步研究,我发现 SIGUSR1 是由主线程处理的,而不是控制线程。由于调用的 fn_recv 具有像 malloc、free 这样的函数,我认为这些函数是不可重入的,所以它导致了问题。
我通过屏蔽 SIGUSR1 信号并创建一个单独的线程来设置信号处理程序而不是控制线程来解决它,以避免干扰系统/函数调用。我在新线程中取消屏蔽 SIGUSR1 信号,以确保它仅由该新线程处理。我现在能够多次传输数据并切换套接字 ID,而不会出现停顿。如果有人需要更多详细信息,请告诉我。 基本上在主线程中屏蔽信号并在子线程中取消它就可以了!
关于c - 异步信号导致套接字 I/O 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11753229/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!