我想为我的程序添加IPv6支持,并遇到奇怪的错误。 我想打开接受连接的套接字。 这是我的情况: 首先我使用getaddrinfo()来查找套接字configuration: struct addrinfo hint, *info = NULL; memset((void *)&hint, 0, sizeof(hint)); hint.ai_family = AF_INET6; hint.ai_flags = AI_PASSIVE | AI_NUMERICSERV; hint.ai_socktype = SOCK_STREAM; if ((error = getaddrinfo(NULL, "1234", &hint, &info))) { /* some error handling */ } 我在info产生非NULL结果。 然后我想创build套接字: socket(info->ai_family, info->ai_socktype, info->ai_protocol) 这里我得到-1 strerror(errno) 返回Address family not supported by protocol 我认为getaddrinfo()只返回可以绑定的地址,我期望它在这种情况下返回NULL。 我错过了什么? 我想补充说我的eth0目前没有IPv6地址。 […]
我试图使用IPv6套接字连接到IPv4地址使用IPv4映射的IPv6地址,在Linux(debian-lenny-64 2.6.26-2-amd64) #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <errno.h> #include <stdlib.h> #include <stdio.h> int main(int argc, void **argv) { struct addrinfo *sa; struct addrinfo *ra; int err = getaddrinfo("2001:DB8::2", 0, 0, &sa); int fd = socket(sa->ai_family, SOCK_DGRAM, 0); int v6only = 0; err = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&v6only, sizeof(v6only)); err = bind(fd, sa->ai_addr, […]
我试图在C中实现一个发送/接收原始以太网帧的协议,并且在Linux环境中使用poll()和recvfrom()遇到了一些问题。 我认为我的问题主要是概念性的,所以我现在要避免发布我的代码。 我有两个传入数据的套接字,并且poll()正被用于通过其返回值和关联的pollfd结构的状态来指示何时在任一套接字上准备好数据。 当我第一次运行这个程序的时候,这就是我的工作。 为了testing的目的,我只对ARP帧感兴趣,我可以使用poll()等待一个ARP帧到达。 当它到达时,我调用recvfrom()将数据复制到可以处理它的位置。 所有这一切工作正常。 问题是继续调用poll()继续报告数据已经准备好从套接字读取,即使没有新的数据到达套接字。 一旦我调用recvfrom()并从套接字中读取数据,我希望poll()等到新的帧到达之后才报告数据已准备好。 我之前从来没有使用poll() ,所以我不确定是否需要明确的步骤来“清除”描述符,以便它将停止导致poll()报告正在准备好的数据,直到有新帧出现为止。在调用poll()之前,我正在清除pollfd结构的revents成员,但每次调用poll()都将revents的值设置为1。 我已经浏览了poll()手册页,而且我还没有find有关此信息的运气。 我觉得我误解了socket / polling是如何在高层工作,所以任何帮助,将不胜感激。 这是我的大部分代码。 我实际上已经简化了这个例子的代码,只包含一个套接字。 所有这些也都被封装在课堂上,并且散播出去,但是像这样重写就再现了我的问题。 我的最终代码对API调用进行了错误检查,并复制我的接收缓冲区来处理框架,而不仅仅是打印内容,但除此之外它几乎是一样的。 #include <stdio.h> #include <stdint.h> #include <sys/socket.h> #include <netinet/in.h> #include <fcntl.h> #include <poll.h> #include <linux/if_ether.h> int main() { uint8_t sendBuffer_[1536]; uint8_t receiveBuffer_[1536]; struct pollfd pollStruct[1]; printf("Making socket…"); int mySocket = socket( AF_PACKET, SOCK_RAW, htons(ETH_P_ARP) ); fcntl(mySocket, F_SETFL, […]
对于基准testing,我目前正在寻找一种方法来testing一些似乎有问题的TCP连接。 为此,我想在程序运行时logging一些性能指标。 我已经logging了每个操作的时间,但这只是告诉我这个用例的传输时间太长了。 我需要的是一个简单的方法来跟踪定期读取/写入的字节数。 通常我只是手动添加基准testing,但套接字在库中使用,所以我不能轻松地进行读写调用。 我的猜测是,有一些现成的Linux提供的方法,可以做到这一点,但我找不到它。 我已经看过getsockopt()与TCP_INFO标志的可能性,但从文档我只能看到如何获得窗口大小等,而不是读取/写入的字节数。 有没有办法从Linux获取这些信息?
我知道TIME_WAIT是为了防止一个连接的延迟段被误解为后续连接的一部分。 丢弃在连接到达时处于TIME_WAIT等待状态的任何段。 在我的实验中,当客户端发送RST数据包而不是FIN数据包时,我看不到TIME_WAIT 。 为什么? 服务器 while (1) { int len = sizeof(struct sockaddr); fd = accept(sfd, &remote, &len); read(fd, buf, sizeof(buf)); strcpy(buf, "Hello Client"); write(fd, buf, strlen(buf)); close(fd); } 客户 res = connect(sfd, result->ai_addr, result->ai_addrlen); strcpy(buf, "Hello Server!"); write(sfd, buf, strlen(buf)); close(sfd); 注意:客户端发送RST而不是FIN,因为它在closures套接字之前不读取服务器已经发送的缓冲数据。
我有一个Linux应用程序,讲TCP,并帮助分析和统计,我想修改它发出的一些TCP数据包中的数据。 我宁愿这样做,而不是黑客的Linux TCP堆栈。 到目前为止,我的想法是做一个“TCP数据包修改器”的桥梁。 我的想法是通过桥的一侧的tun / tap设备连接到应用程序,并通过桥的另一侧的原始sockets连接到网卡。 我担心的是,当你打开一个原始套接字时,它仍然会将数据包发送到Linux的TCP协议栈,所以即使我想,也不能修改它们并发送它们。 它是否正确? 该桥的伪C代码草图如下所示: tap_fd = open_tap_device("/dev/net/tun"); raw_fd = open_raw_socket(); for (;;) { select(fds = [tap_fd, raw_fd]); if (FD_ISSET(tap_fd, &fds)) { read_packet(tap_fd); modify_packet_if_needed(); write_packet(raw_fd); } if (FD_ISSET(raw_fd, &fds)) { read_packet(raw_fd); modify_packet_if_needed(); write_packet(tap_fd); } } 这看起来是可能的,还是有其他更好的方法来实现相同的事情? (TCP数据包桥接和修改)
我正在C中创build一个简单的服务器。现在我无法创build套接字来侦听传入的连接。 我在一个运行在VirtualBox内的x86 Debian发行版上。 我的代码如下: #define _POSIX_SOURCE #include <stdio.h> #include <pthread.h> /* threads, yo */ #include <stdlib.h> #include <memory.h> /* memset */ #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #include <netdb.h> #include <arpa/inet.h> /* helpers like inet_ntop */ #include <netinet/in.h> void listenInput(); void* handleConn(void* args) { printf("Handling connection!\n"); listenInput(); return NULL; } void acceptData(int socket) […]
我正在编写一个使用TCP通过networking进行通信的程序。 如果用户提供ip地址作为命令行参数,程序将尝试连接到该地址。 如果没有,它将等待其他人连接。 为了清楚起见,即使它是p2p连接,我将调用等待其他人连接作为服务器和另一个作为客户端。 服务器没有问题接收客户端发送的任何文本消息。 但是,客户端只有在发送自己的消息时才会收到来自服务器的文本消息。 我如何解决这个问题,让客户端立即收到消息? 这是我的代码片段 a.sin_family = AF_INET; a.sin_addr.s_addr = iet_addr(SERVER_IP); addr.sin_port = htons((unsigned short)SERVER_PORT); 在这里,我使用了用于发送的相同套接字。 我需要创build一个新的听力? fgets(buffer,sizeof(buffer),stdin); send(socket,buffer,strlen(buffer),0); b = recv(socket,buffer,sizeof(buffer),0); buffer[b] = 0; printf("%s",buffer); 编辑:这是为了监听套接字 add.sin_family = AF_INET; add.sin_addr.s_addr = htonl(atoi("127.0.0.1")); add.sin_port = htons((unsigned short)NEWPORT); 编辑:这是绑定代码 bind(socket,(struct sockaddr *)&add,sizeof(add));
我想连接到一个服务器,并同步地写(2)到它。 在某些时候,缓冲区正在填满,我需要阅读(2)让我继续写作。 读(2)当然是不必要的复制大量的字节,而且如果我不知道有多less字节的话,它会被阻塞。 我怎样才能丢弃TCP套接字传入的字节? 我试过ioctl(sockfd, I_SRDOPT, RMSGD)但它返回错误EFAULT Bad address 。
我工作在一个非阻塞的C tcp套接字的Linux系统。 我读过非阻塞模式,如果没有错误,“send”命令将立即返回“发送的字节”。 我猜这个返回值实际上并不意味着这些数据已经传递到目的地,而是数据已经传递给内核内存进行处理和发送。 如果是这样的话,我的应用程序将如何知道哪个数据包真的被内核发送到另一端,假定networking连接有一些问题,并且内核决定在几分钟内重新尝试几次后才放弃后来? 我问,因为我希望我的应用程序以后重新发送这些失败的数据包。