Tag: 套接字

使用write()系统调用编写完整缓冲区

我想使用write系统调用在TCP套接字上写一个填充BUFF_SIZE字节的缓冲区: #include ssize_t write(int fd, const void *buf, size_t count); 文件说明了这一点 write()写入从缓冲区指向buf的count个字节到文件描述符fd引用的文件。 当然,写入的实际字节数可以通过返回值来检测。 但是,如果我想确保通过连接发送整个字节缓冲区,那么这样做的好方法是什么? 到目前为止,我在想: while ( (ch = fgetc(pipe) ) != EOF ) { buff[ 0 ] = ch; bytes_in_buff++; // fill a buffer’s worth of data from the pipe for (int i = 1; i < BUFF_SIZE; ++i, ++bytes_in_buff) { if ( (ch […]

UDP套接字集超时

我试图在UDP套接字上设置100ms超时。 我正在使用C.我在下面发布了我的代码的相关部分。 我不确定为什么这不是超时,但只是在它没有收到段时挂起。 这仅适用于未使用bind()方法绑定的套接字吗? #define TIMEOUT_MS 100 /* Seconds between retransmits */ if ((rcv_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) DieWithError("socket() failed"); if ((rcv_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) DieWithError("socket() failed"); //set timer for recv_socket static int timeout = TIMEOUT_MS; setsockopt(rcv_sock, SOL_SOCKET, SO_RCVTIMEO,(char*)&timeout,sizeof(timeout)); if(recvfrom(rcv_sock, ackBuffer,sizeof(ackBuffer), 0, (struct sockaddr *) &servAddr2, &fromSize) < 0){ //timeout […]

何时char *对于严格的指针别名是安全的?

我一直在尝试理解严格的别名规则,因为它们适用于char指针。 这是陈述: 始终假定char *可以引用任何对象的别名。 好的,在套接字代码的上下文中,我可以这样做: struct SocketMsg { int a; int b; }; int main(int argc, char** argv) { // Some code… SocketMsg msgToSend; msgToSend.a = 0; msgToSend.b = 1; send(socket, (char*)(&msgToSend), sizeof(msgToSend); }; 但接下来是这个声明 相反的情况并非如此。 将char *转换为除char *之外的任何类型的指针并取消引用它通常违反严格别名规则。 这是否意味着当我收回一个char数组时,当我知道消息的结构时,我无法重新解释转换为结构: struct SocketMsgToRecv { int a; int b; }; int main() { SocketMsgToRecv* pointerToMsg; char msgBuff[100]; […]

为什么我不能在Ubuntu中创建原始套接字?

我正在学习如何在Linux中使用原始套接字。 我正在尝试创建一个这样的套接字: if ((sd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) { perror("socket() failed"); exit(-1); } 但我在发布后获得的是: socket()失败:不允许操作 我知道只有root可以创建原始套接字,但如果我用SUID位或sudo运行它 – 问题是一样的。 怎么了? 该系统是Ubuntu 11.04。 也许我包括不必要的标题? #include #include #include #include #include #include #include #include #include #include #include #include 我想知道 – 为什么SUID没用?

从套接字选择中断

我有一个循环,基本上每隔几秒(超时后)调用它: while(true){ if(finished) return; switch(select(FD_SETSIZE, &readfds, 0, 0, &tv)){ case SOCKET_ERROR : report bad stuff etc; return; default : break; } // do stuff with the incoming connection } 因此,基本上每隔几秒(由tv指定),它会重新激活监听。 这是在线程B(不是主线程)上运行的。 有时我想从线程A(主线程)立即结束这个接受器循环,但似乎我必须等到时间间隔结束。 有没有办法从另一个线程中断选择函数,以便线程B可以立即退出?

对send()的多次调用合并为一次调用recv()

我有一个客户端 – 服务器应用程序。 客户端使用两个不同的send()调用发送一个字符串,后跟一个整数。 这两个数据应该存储在服务器上的两个不同变量中。 问题是发送的两个变量都是在recv()调用时收到的。 因此,由两个不同的send() s send()的两个字符串被链接并存储在第一个recv()的缓冲区中。 server.c: printf(“Incoming connection from client %s:%i accepted\n”,inet_ntoa(clientSocketAddress.sin_addr),ntohs(clientSocketAddress.sin_port)); memset(buffer,0,sizeof(buffer)); int sizeofMessage; if ((recv(clientSocket,buffer,MAXBUFFERSIZE,0)==sizeofMessage)<0) { printf("recv failed."); closesocket(serverSocket); clearWinsock(); return EXIT_FAILURE; } char* Name=buffer; printf("Name: %s\n",Name); if ((recv(clientSocket,buffer,MAXBUFFERSIZE,0))<0) { printf("bind failed."); closesocket(serverSocket); clearWinsock(); return EXIT_FAILURE; } int integer=ntohs(atoi(buffer)); printf("integer: %i\n",intero); client.c: if (send(clientSocket,Name,strlen(Name),0)!=strlen(Name)) { printf(“send failed”); closesocket(clientSocket); clearWinsock(); […]

我如何使用setsockopt(SO_REUSEADDR)?

我在覆盆子pi上运行自己的http服务器。 问题是当我停止程序并重新启动它时,端口不再可用。 有时我在收到大量请求时会遇到同样的问题。 我想使用SO_REUSEADDR,这样即使发生错误我也可以继续使用该端口但是没有运气设置它。 以下是我的代码。 我得到的错误是“绑定时出错:地址已在使用中”。 #include #include #include #include #include #include #include void error(const char *msg) { perror(msg); exit(1); } int main(int argc, char *argv[]) { printf(“Starting Listener\n”); int sockfd, newsockfd, portno; socklen_t clilen; char buffer[256]; struct sockaddr_in serv_addr, cli_addr; int n; if (argc < 2) { fprintf(stderr,"ERROR, no port provided\n"); exit(1); } sockfd […]

使用select()表示非阻塞套接字

我正在尝试使用select函数在服务器和1个客户端(不再)之间进行非阻塞i / o,其中通信流畅(可以随时发送而另一个将在不等待发送的情况下接收)。 我找到了一些包含一些代码的教程,并尝试将其改编为我的。 这就是我所拥有的 – 服务器 #define PORT “4950” #define STDIN 0 struct sockaddr name; void set_nonblock(int socket) { int flags; flags = fcntl(socket,F_GETFL,0); assert(flags != -1); fcntl(socket, F_SETFL, flags | O_NONBLOCK); } // get sockaddr, IPv4 or IPv6: void *get_in_addr(struct sockaddr *sa) { if (sa->sa_family == AF_INET) return &(((struct sockaddr_in*)sa)->sin_addr); return &(((struct sockaddr_in6*)sa)->sin6_addr); […]

设置winsock recvfrom的超时时间

我试图设置一个阻塞套接字,在尝试端口上的recvfrom()16 ms后超时。 平台是Windows。 我在网上看了很多例子,看起来很简单,我似乎无法让它发挥作用。 任何帮助,将不胜感激! #include #include #pragma comment(lib, “ws2_32.lib”) #define PORT_NUM 8001 int main(void) { std::string localIP; sockaddr_in localAddr; sockaddr_in remoteAddr; hostent* localhost; char buffer[1024]; WSADATA wsData; int result = WSAStartup(MAKEWORD(2,2), &wsData); // winsock version 2 localhost = gethostbyname(“”); localIP = inet_ntoa(*(in_addr*)*localhost->h_addr_list); localAddr.sin_family = AF_INET; localAddr.sin_port = htons(PORT_NUM); // Set Port Number localAddr.sin_addr.s_addr = […]

为什么改变SO_RCVBUF的值不起作用?

我正在创建一个程序来创建一个RAW套接字,以便读取所有流量。 在socket()和recvfrom()的调用之间(最后一个是循环以从缓冲区中取出所有数据包)我等待5s。 当我运行程序时,我用“快速模式”(快速填充缓冲区)的hping3命令向我的程序发送大约200个数据包。 只要5s过去,我的程序就会从缓冲区中提取大约150个数据包。 我尝试更改接收缓冲区的大小以获得更好的结果: int a = 65535; if ( (setsockopt(sockfd, 0, SO_RCVBUF, &a ,sizeof(int)) ) < 0 ) { fprintf(stderr, "Error setting sock opts..\n"); } 但是,无论是“a”,1还是10000000的值,它似乎都没有变化,我仍然可以从缓冲区获得~150个数据包。 有什么问题? 编辑:使用getsockopt调用validation«a»的值。