ioctlsocket函数,socket函数的用法

1,socket函数的用法m_hSocket=socket(PF_INET,SOCK_STREAM,0);sockAddr.sin_family=AF_INET;sockAddr.sin_port=m_iPort;sockAddr.sin_addr.S_un.S_addr=dwIPAddr;int nConnect = connect(m_hSocket,(LPSOCKADDR)&sockAddr,sizeof(sockAddr));
2,自己做的类库 封装socket类 请问怎样实现非阻塞模式当使用socket()函数和WSASocket()函数创建套接字时,默认都是阻塞的 。在创建套接字之后,通过调用ioctlsocket()函数,将该套接字设置为非阻塞模式 。//-------------------------// Set the socket I/O mode: In this case FIONBIO// enables or disables the blocking mode for the// socket based on the numerical value of iMode.// If iMode = 0, blocking is enabled;// If iMode != 0, non-blocking mode is enabled.u_long iMode = 1;//non-blocking mode is enabled.ioctlsocket(m_socket, FIONBIO, &iMode); //设置为非阻塞模式套接字设置为非阻塞模式后 , 在调用Windows Sockets API函数时,调用函数会立即返回 。大多数情况下,这些函数调用都会调用“失败”,并返回WSAEWOULDBLOCK错误代码 。说明请求的操作在调用期间内没有时间完成 。通常,应用程序需要重复调用该函数,直到获得成功返回代码 。不同的Windows Sockets API函数 , 在调用失败时返回的WSAEWOULDBLOCK错误代码具有不同的含义需要说明的是并非所有的 Windows Sockets API 在非阻塞模式下调用,都会返回 WSAEWOULDBLOCK 错误 。例如,以非阻塞模式的套接字为参数调用 bind() 函数时,就不会返回该错误代码 。当然,在调用 WSAStartup() 函数时更不会返回该错误代码,因为该函数是应用程序第一调用的函数,当然不会返回这样的错误代码 。要将套接字设置为非阻塞模式,除了使用 ioctlsocket() 函数之外,还可以使用 WSAAsyncselect() 和 WSAEventselect() 函数 。当调用该函数时 , 套接字会自动地设置为非阻塞方式:The WSAAsyncSelect function automatically sets socket s to nonblocking mode, regardless of the value of lEvent .The WSAEventSelect function automatically sets socket s to nonblocking mode, regardless of the value of lNetworkEvents .你好!可以使用回调,或者事件的方式进行非阻塞处理 。如有疑问,请追问 。
3,ioctl怎么使用BOOL IOCtl(longlCommand,DWORD* lpArgument );DWORD dwParam = 0 ;DWORD* pAug = &dwParam .1. cmd = FIOBIO*pAug = 1 ; // 非0值表示设置ioctl为非阻塞*pAug = 0 ; // 0表示设置ioctl为阻塞.pAug用于设置. 2. cmd = FIONREAD*pAug = operational result // pAug存储的是读取的结束// 如果socket = sock_stream, *pAug = bytes read(读取的字节数)// 如果socket = sock_datagram, *pAug = 第一个数据包(datagram)的大小 pAug用于接收3. cmd = SIOCATMARK*pAug = read result// 如果没有重要的数据等待读取,操作返回非0值// 否则返回0pAug用于接收static int motor_driver_ioctl(struct inode *inode, struct file *file, unsigned int cmd,unsigned long arg)get_user(val,(int __user*)arg);//内核空间不能直接取用户空间的指针的 switch (cmd){在windows系统中应用程序不能直接访问硬件,必须通过驱动程序,而硬件千变万化 , 相应的驱动程序也有很大的变化,操作系统必须有一个抽象的层次来弥合应用程序和驱动程序 。windows系统沿用了unix系统中的概念 , 在unix系统中,一切外部资源都是文件,文件可以很好的抽象硬件,对于系统核心而言,一切外设不过就是输入输出的数据,类同于文件操作 。在windows中提供一切应用程序访问硬件的api就是我们熟知的文件操作函数 , 就是createfile,openfile,readfile,writefile,等等,他还有一个特殊的函数,理论上并不需要这个函数,但是有了这个函数可以简化应用程序设计,就iocontrol 。它可以让应用程序向外设发送指令(实际上,writefile完全可以替代它的用途) 。这些基本的访问驱动程的api构成了基础的抽象,其他的应用程序api也要通过这些函数来访问外设,只是他们根据特定的用途进行了特化,比如winsock他最终访问网卡还是要通过这些基本的io函数的 。ioctl错误,就是说应用程序在调用iocontrol这个函数的时候发生了故障 , 可能是硬件故障,也可能是错误的驱动程序,或者这个u盘不支持标准的格式化方式 。【ioctlsocket函数,socket函数的用法】
4,socket接收不定长数据有没有好办法TCP协议通信,接收方接收数据的前后次序与发送方一致 , 但数据包不一定一致 。打个比方,发送方按顺序发送了2个数据包,接收可能仅接收1次就能全部收到,也可能需要收2次才能收到,也可能收3次,每次收到的数据大小不一定和发送方发送的数据包大小一样 , 但最终收到的总数据是一致的 。从你的程序来看,客户端连续发送2包数据,服务器端有可能一次就全部接到 , 也可能分2次收到,也可能会收2次以上才能收到 。如果在发送“########helloworld”和“######whatisit”之间增加一些延时语句,比如延时1秒,那么可以肯定服务器端只能收到1次,因为在发送第1包数据的时候,服务器端就接收到一次数据,而在发送第2包数据时,服务器已经不再有接收动作了 。就现在的客户端程序来说,如果要在服务器端收到所有数据 , 可以考虑在服务器端循环接收数据,拼装数据,直到收不到数据为止,然后输出所有接收到的数据 。while(1)int rr;sock_fd = accept( sock, NULL, NULL);retval = 0;while(1)rr = recv( sock_fd, buf1, MAX_BUFLEN, 0 );if(rr==0) break;memcpy(buf+retval,buf1,rr);retval+=rr;}printf("buf= %s\n ##retval=%d\n",buf,retval);write(sock_fd,"get the call\n",sizeof("get the call\n")-1);}可以试试看 。仅供参考 。查到个函数ioctlsocket while(1) sock_fd = accept( sock, NULL, NULL);retval = 0; int iMode = 1; //0:阻塞 ioctlsocket(sock_fd,FIONBIO, (u_long FAR*) &iMode);//非阻塞设置 while(1) ........ }1)如果“数据条数”定义是:客户端发送数据帧的数量,那么,服务器每当收到一次客户端的数据帧 , 计数就加1;例如,客户端a连续发送了“你好”,“我在这里”两条信息,服务器的计数就应该增加2;2)服务器可以接收来自多个客户端的数据 , 可以分别统计每个客户端数据条数,也可以统计所以客户端数据总的条数 。针对上面两个需求 , 实现起来大致框架如下:1)定义一个dictionarynum,用来计数 dictionary num= new dictionary();其中,泛型参数string用于表示客户端;int用于计数 2)每当服务器接收到来自客户端数据后,可以获得客户端的ipendpoint clientep,将clientep转换成字符串,作为dictionary 的键值,用来标识客户端 string client = clientep.tostring(); if(!num.containskey(client)) { //在集合中添加一个客户端计数项 num.add(client, 0); } //数据条数加1 num[client]++;3)分别统计并显示每个客户的数据条件 foreach( var c in num) { console.writeline("客户端,总数", c.key, c.value); }4)统计并显示服务器接收到所有客户端数据条数的总数 var qry = from c in num.values select c console.writeline("接收总数", qry.sum());5,tcp ip 连接 有效时间 C1.是一直有效 。2.不会阻塞,recv会返回SOCKET_ERROR 。3.直接关闭socket连接,重连4.send会返回SOCKET_ERROR5.中途断网只能重新连接从一个套接口接收数据 。#include <winsock.h>int pascal far recv( socket s, char far* buf, int len, int flags);s:一个标识已连接套接口的描述字 。buf:用于接收数据的缓冲区 。len:缓冲区长度 。flags:指定调用方式 。注释:本函数用于已连接的数据报或流式套接口s进行数据的接收 。对sock_stream类型的套接口来说,本函数将返回所有可用的信息,最大可达缓冲区的大小 。如果套接口被设置为线内接收带外数据(选项为so_oobinline),且有带外数据未读入 , 则返回带外数据 。应用程序可通过调用ioctlsocket()的socatmark命令来确定是否有带外数据待读入 。对于数据报类套接口 , 队列中第一个数据报中的数据被解包 , 但最多不超过缓冲区的大小 。如果数据报大于缓冲区,那么缓冲区中只有数据报的前面部分 , 其他的数据都丢失了,并且recv()函数返回 wsaemsgsize错误 。如果没有数据待读,那么除非是非阻塞模式,不然的话套接口将一直等待数据的到来 , 此时将返回socket_error错误,错误代码是wsaewouldblock 。用select()或wsaasynselect()可以获知何时数据到达 。如果套接口为sock_stream类型 , 并且远端“优雅”地中止了连接,那么recv()一个数据也不读取,立即返回 。如果立即被强制中止 , 那么recv()将以wsaeconnreset错误失败返回 。在套接口的所设选项之上,还可用标志位 flag来影响函数的执行方式 。也就是说 , 本函数的语义既取决于套接口选项,也取决于标志位参数 。标志位可取下列值:值 意义msg_peek查看当前数据 。数据将被复制到缓冲区中,但并不从输入队列中删除 。msg_oob 处理带外数据(参见2.2.3节具体讨论) 。返回值:若无错误发生,recv()返回读入的字节数 。如果连接已中止 , 返回0 。否则的话,返回socket_error错误 , 应用程序可通过wsagetlasterror()获取相应错误代码 。错误代码:wsanotinitialised:在使用此api之前应首先成功地调用wsastartup() 。wsaenetdown:windows套接口实现检测到网络子系统失效 。wsaenotconn:套接口未连接 。wsaeintr:阻塞进程被wsacancelblockingcall()取消 。wsaeinprogress:一个阻塞的windows套接口调用正在运行中 。wsaenotsock:描述字不是一个套接口 。wsaeopnotsupp:指定了msg_oob,但套接口不是sock_stream类型的 。wsaeshutdown:套接口已被关闭 。当一个套接口以0或2的how参数调用shutdown()关闭后,无法再用recv()接收数据 。wsaewouldblock:套接口标识为非阻塞模式,但接收操作会产生阻塞 。wsaemsgsize:数据报太大无法全部装入缓冲区 , 故被剪切 。wsaeinval:套接口未用bind()进行捆绑 。wsaeconnaborted:由于超时或其他原因,虚电路失效 。wsaeconnreset:远端强制中止了虚电路 。用char *buffer="",缓存区大小是0 , 当然收不到 。用char buffer[256],缓冲区大小是256 , 当然可以 。选C建议你去网上找个列子 一定要知道 套接字是不干活的 只是负责连接 真正干活的是主对话框

    推荐阅读