Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sockets sendmsg()不';t按预期运行_Sockets_Unix - Fatal编程技术网

Sockets sendmsg()不';t按预期运行

Sockets sendmsg()不';t按预期运行,sockets,unix,Sockets,Unix,我用一对简单的客户机和服务器编写了一个程序,第一个程序生成一组字符串并通过socket提供的API发送,即sendmsg(),第二个程序通过epoll接收字符串 根据tcpdump捕获的内容和客户端执行的结果,客户端能够连接到服务器并正确发送几条消息,但只有少数几条,以下字符串未能完全接收,并且在服务器打印接收到的代码结束时,同一字符串段存在无限重复 如果需要更多详细信息,请与我联系 顺便问一下,是否有任何推荐的参考文献提供了有关sendmsg()用法的详细说明 这是客户端的主要代码: void

我用一对简单的客户机和服务器编写了一个程序,第一个程序生成一组字符串并通过socket提供的API发送,即sendmsg(),第二个程序通过epoll接收字符串

根据tcpdump捕获的内容和客户端执行的结果,客户端能够连接到服务器并正确发送几条消息,但只有少数几条,以下字符串未能完全接收,并且在服务器打印接收到的代码结束时,同一字符串段存在无限重复

如果需要更多详细信息,请与我联系

顺便问一下,是否有任何推荐的参考文献提供了有关sendmsg()用法的详细说明

这是客户端的主要代码:

void MultithreadedLogAnalyzer::SendToServer(string Addr,uint16_t Port) {
    int connfd = socket(AF_INET,SOCK_STREAM,0);
    sockaddr_in servaddr;

    servaddr.sin_family = AF_INET;

    servaddr.sin_port = htons(Port);
    inet_pton(AF_INET,Addr.c_str(),&servaddr.sin_addr);

    /*connect failure process to be added*/

    int st = connect(connfd,(struct sockaddr *)&servaddr,sizeof(sockaddr));
    if(-1 == st){
        perror("connection failed");
    }   
    Handle(connfd,servaddr);

    close(connfd);

}

void MultithreadedLogAnalyzer::Handle(int connfd,const sockaddr_in &servaddr){
  int n= 0,counter =0;
  for(vector<string>::iterator si = mFilterResult.begin();si != mFilterResult.end(); ++si)
  {   
      msghdr msg;
      iovec iov;
      memset(&msg,0,sizeof(msg));
      memset(&iov,0,sizeof(iov));
      msg.msg_control = NULL;
      msg.msg_controllen = 0;
      msg.msg_flags = 0;
      char data[1024];
      memset(data,0, 1024);
      memcpy(data,si->c_str(),si->size());
      iov.iov_base = data;
      iov.iov_len = (*si).size() ;//check first to locate error
      cout << "size:" << (*si).size() << endl;
      msg.msg_name = NULL;
      msg.msg_namelen = 0;
      msg.msg_iov = &iov;
      msg.msg_iovlen = 1;
      //msg.msg_accrights = NULL;
      //msg.msg_accrightslen = 0; 
      n = sendmsg(connfd,&msg,0);
      cout << "n: " <<  n << endl;
      ++counter;
      if (-1 == n)
          perror("sendmsg error\n");
  }
  cout << "number of strings send: " << counter << endl;
void multi-threadedloganalyzer::SendToServer(字符串地址,uint16\u t端口){
int connfd=套接字(AF_INET,SOCK_STREAM,0);
servaddr中的sockaddr_;
servaddr.sin_family=AF_INET;
servaddr.sinu端口=htons(端口);
inet_pton(AF_inet,Addr.c_str(),&servaddr.sin_Addr);
/*要添加的连接失败进程*/
int st=connect(connfd,(struct sockaddr*)和servaddr,sizeof(sockaddr));
如果(-1==st){
perror(“连接失败”);
}   
手柄(connfd、servaddr);
关闭(connfd);
}
void multi-threadedLogAnalyzer::Handle(int-connfd,const-sockaddr\u in&servaddr){
int n=0,计数器=0;
对于(向量::迭代器si=mFilterResult.begin();si!=mFilterResult.end();+si)
{   
msghdr msg;
iovec-iov;
memset(&msg,0,sizeof(msg));
memset(&iov,0,sizeof(iov));
msg.msg_control=NULL;
msg.msg_controllen=0;
msg.msg_标志=0;
字符数据[1024];
memset(数据,0,1024);
memcpy(data,si->c_str(),si->size());
iov.iov_base=数据;
iov.iov_len=(*si).size();//首先检查以查找错误
库特
这是在错误的位置。它应该是在
c=recvmsg(…)之后立即进行的测试;
如果(c>0)
,那么它应该是
,如果
c==-1
,那么您应该立即调用
perror()
,或者在消息中使用
errno
strerror()
,而不调用任何其他系统调用


基本上,您在流结束后继续接收;在流结束后打印垃圾或错误;并且在打印邮件时忽略了实际邮件长度。

非常感谢您的回答,尽管我已经解决了我的问题。问题是由于重复发送邮件而导致的,对其行为没有任何控制,而h似乎已超过TCP发送窗口限制,并导致我无法理解结果。该问题是由于忽略流的结尾和消息长度造成的。
recvmsg()
在流的结尾返回零。此时停止。如果出现错误,也会停止,如果出现错误,则调用
peror()
,或在消息中使用
errno
strerror()
。我确实忽略了流的结尾,但这没问题,因为msg是用值0初始化的,不会打印任何内容,并且不会或已经在此处发生错误。字符串结尾由“\0”标记,当c_str()我打电话给你了。你可以试一试。谢谢你的进一步解释。
#include <sys/socket.h>
#include <stdlib.h>
#include <iostream>
#include <string.h>
#include <fcntl.h>
#include <stdio.h>
#include <strings.h>
#include <netinet/in.h>
#include <sys/epoll.h>

#define POLLSIZE  100
#define STRINGSIZE 300
using namespace std;
void handle(int fd){
int c = 0;
do{
    msghdr msg;
    memset(&msg,0,sizeof(msghdr));
    msg.msg_name = NULL;
    msg.msg_namelen = 0;
    char data[1024];
    iovec iov;
    iov.iov_base = data;
    iov.iov_len = 1024;
    msg.msg_iov = &iov;
    msg.msg_iovlen = 1;
    msg.msg_control = NULL;
    msg.msg_controllen = 0;
    msg.msg_flags = 0;
    c = recvmsg(fd,&msg,0);
    if(msg.msg_iovlen==0
            ){
        return;
    }
        cout << "msg length:" << msg.msg_iovlen<< endl;
        cout << string((char *)(msg.msg_iov[0].iov_base)) << endl;
    }while(c != -1);
}

int main() {
    int listenfd;
    listenfd = socket(AF_INET, SOCK_STREAM, 0);
    sockaddr_in servaddr,cliaddr;
    socklen_t socklen = 0;
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

int serverPort = 2000;
servaddr.sin_port = htons(serverPort);

bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
int listennumnber = 20;
listen(listenfd,listennumnber);

//the rest to be commented
int epfd = epoll_create(POLLSIZE);
if (epfd < 0)
    perror("epoll_create");
struct epoll_event ev;
ev.events = EPOLLIN|EPOLLET;
ev.data.fd = listenfd;
if(epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev) < 0)
    perror("epoll_ctl");
int curfds  = 1;
struct epoll_event *events = (struct epoll_event*)malloc(sizeof(struct epoll_event));

for (;;){
    int n;
    int nfds = epoll_wait(epfd,events,curfds,-1);
    if (-1 == nfds)
        continue;
        for(n = 0;n < nfds; ++n){
            if(events[n].data.fd == listenfd){
                int connfd = accept(listenfd,(struct sockaddr *)&cliaddr ,&socklen);
                cout << "connect established through connfd: " << connfd << endl;
                    if (connfd < 0)
                        continue;
            //      if(setnonblocking(connfd) < 0)
            //          perror("set setnonblocking error");
                    ev.events = EPOLLIN | EPOLLET;
                    ev.data.fd = connfd;
                    if(epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev) < 0)
                        return -1;
                    curfds++;
                    continue;
            }
            handle(events[n].data.fd);
        }
}

return 0;
}
    cout << "msg length:" << msg.msg_iovlen<< endl;
    cout << string((char *)(msg.msg_iov[0].iov_base)) << endl;
}while(c != -1);