Linux SOCKET编程详解(3)
a) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。
b) Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
网络字节序:4个字节的32 bit值以下面的次序传输:首先是0~7bit,其次8~15bit,然后16~23bit,最后是24~31bit。这种传输次序称作大端字节序。由于TCP/IP首部中所有的二进制整数在网络中传输时都要求以这种次序,因此它又称作网络字节序。字节序,顾名思义字节的顺序,就是大于一个字节类型的数据在内存中的存放顺序,一个字节的数据没有顺序的问题了。
所以:在将一个地址绑定到socket的时候,请先将主机字节序转换成为网络字节序,而不要假定主机字节序跟网络字节序一样使用的是Big-Endian。由于这个问题曾引发过血案!公司项目代码中由于存在这个问题,导致了很多莫名其妙的问题,所以请谨记对主机字节序不要做任何假定,务必将其转化为网络字节序再赋给socket。
4.3、listen()、connect()函数
如果作为一个服务器,在调用socket()、bind()之后就会调用listen()来监听这个socket,如果客户端这时调用connect()发出连接请求,服务器端就会接收到这个请求。
int listen(int sockfd, int backlog);int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
listen函数的第一个参数即为要监听的socket描述字,第二个参数为相应socket可以排队的最大连接个数。socket()函数创建的socket默认是一个主动类型的,listen函数将socket变为被动类型的,等待客户的连接请求。
connect函数的第一个参数即为客户端的socket描述字,第二参数为服务器的socket地址,第三个参数为socket地址的长度。客户端通过调用connect函数来建立与TCP服务器的连接。
4.4、accept()函数
smtp是个请求/响应协议,它监听25号端口,用于接收用户的mail请求,并与远端mail服务器建立smtp连接。对于一个服务器套接字调用listen()成员函数进行监听,对于一个客户套接字调用connect()成员函数来请求连接。使用socket进行client/server程序设计的一般连接过程是这样的:server端listen(监听)某个端口是否有连接请求,client端向server端发出connect(连接)请求,server端向client端发回accept(接受)消息。
socklen_t addrlen = sizeof(struct sockaddr)。sendto(sockfd, buf, len, 0, (const sockaddr *)addr, sizeof(struct sockaddr_in))。 */int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)。
参数sockfd
参数sockfd就是上面解释中的监听套接字,这个套接字用来监听一个端口,当有一个客户与服务器连接时,它使用这个一个端口号,而此时这个端口号正与这个套接字关联。当然客户不知道套接字这些细节,它只知道一个地址和一个端口号。
参数addr
该参数与 g 代码要相对应如下: 工件坐标系 1 (g54) ---工件原点返回偏移值---参数 1221 工件坐标系 2 (g55) ---工件原点返回偏移值---参数 1222 工件坐标系 3 (g56) ---工件原点返回偏移值---参数 1223 工件坐标系 4 (g57) ---工件原点返回偏移值---参数 1224 工件坐标系 5 (g58) ---工件原点返回偏移值---参数 1225 工件坐标系 6 (g59) ---工件原点返回偏移值---参数 1226 在接通电源和完成了原点返回后,系统自动选择工件坐标系 1 (g54) 。调用时输入23和24.5,输入的这2个参数才是真正需要传递给函数的参数,ref int, ref double是告诉alien需要分配空间,调用c函数从栈中获取它的参数,调用结束后将返回结果放到栈中(为了区分返回结果和栈中的其他的值,每个c函数还会返回结果的个数),然后lua函数返回结果值。这个内联表值接收一个输入客户id参数@cid,另外一个输入参数订单年份参数@orderdateyear,返回客户id等于@cid的客户下的所有订单,且订单的订单年份等于@orderdateyear。
参数len
error ,下面来看一些常用的参数,作为send的参数发送整个结构,在project->,双字节对齐等,要不然会出现结构解释的差异。在调用返回时,调用者必须清除栈中的相应内容,在上例中,参数占有12个字节,为了消除这些参数,只需将esp加12即可。bydata传进来的字节数组,用以接受filestream对象中的数据,第2个参数是字节数组中开始写入数据的位置,它通常是0,表示从数组的开端文件中向数组写数据,最后一个参数规定从文件读多少字符.。
如果accept成功返回,则服务器与客户已经正确建立连接了,此时服务器通过accept返回的套接字来完成与客户的通信。
注意:
getmessage从消息队列获取消息,直到有一个“合适”的投递消息可用时才能够返回(阻塞型)。. accept方法用于产生"阻塞",直到接受到一个连接,并且返回一个客户端的socket对象实例。.accept方法用于产生'阻塞',直到接受到一个连接,并且返回一个客户端的socket对象实例。
此时我们需要区分两种套接字,
监听套接字: 监听套接字正如accept的参数sockfd,它是监听套接字,在调用listen函数之后,是服务器开始调用socket()函数生成的,称为监听socket描述字(监听套接字)
连接套接字:一个套接字会从主动连接的套接字变身为一个监听套接字;而accept函数返回的是已连接socket描述字(一个连接套接字),它代表着一个网络已经存在的点点连接。
一个服务器通常通常仅仅只创建一个监听socket描述字,它在该服务器的生命周期内一直存在。内核为每个由服务器进程接受的客户连接创建了一个已连接socket描述字,当服务器完成了对某个客户的服务,相应的已连接socket描述字就被关闭。
由于内核在实现时,可以接收数据的套按字,只有最后一次绑定的可以接收 。原因就在于同样的一幅图,几十字是在描述这幅图还不一定能描述准确。原因说法不一,有的说,因为长沙话中的6与“陆”字同音,而方言中说别人“陆”,有贬损别人“宝里宝气”之意,所以忌讳第6道菜上鱼。
远程客户端(remote client) 即工作站客户端,客户端和服务器在不同主机,他们之间通过网线连 接通讯,即使客户端与服务器在同一主机,他们的通信仍通过tcp/ip 协议 java客户端 即使用wtc、jolt等连接tuxedo server端 目 录 01 02 04 wls是什么 wsl的工作原理 wsl的相关配置 03 wsl的使用的场景 wsl工作原理 wsl作为tuxedo的监听进程,用来监听来自远程客户端的请求。解决方法:检查服务器和客户端的icmp端口是否打开,hlog文件夹里面存放的是实时扫描的病毒日志,通过监听端口传到服务器端,由于服务器和客户端之间有防火墙,没有把icmp端口打开,造成客户端联系不到服务器端,导致hlog里都是些错误日志。与一般的木马相反,反弹端口型木马的服务端(被控制端)使用主动端口,客户端(控制端)使用被动端口,为了隐蔽起见,客户端的监听端口一般开在80,这样,即使用户使用端口扫描软件检查自己的端口,发现的也是类似“tcp服务端的ip地址:1026客户端的ip地址:80established”的情况,稍微疏忽一点你就会以为是自己在浏览网页。
4.5、read()、write()等函数
万事具备只欠东风,至此服务器与客户已经建立好连接了。可以调用网络I/O进行读写操作了,即实现了网咯中不同进程之间的通信!网络I/O操作有下面几组:
read()/write()
recv()/send()
readv()/writev()
recvmsg()/sendmsg()
recvfrom()/sendto()
我推荐使用recvmsg()/sendmsg()函数,这两个函数是最通用的I/O函数,实际上可以把上面的其它函数都替换成这两个函数。它们的声明如下:
structmsghdr*m,size_ttotal_len,intflags)。int(*shutdown)(structsocket*sock,intflags)。int(*accept)(structsocket*sock,structsocket*newsock,intflags)。
函数返回一个非负值是表示成功地读取了多少字节。从一个文件流中读数据,读取count个元素,每个元素size字节.如果调用成功返回count.返回实际读取size*count字节.如不成功,返回实际读取的元素个数。 如果顺利read()会返回实际读到的字节数,最好能将返回值与参数count作比较,若返回的字节数比要求读取的字节数少,则有可能读到了文件尾、从管道(pipe)或终端机读取,或者是read()被信号中断了读取动作。
write函数将buf中的nbytes字节内容写入文件描述符fd.成功时返回写的字节数。失败时返回-1,并设置errno变量。 在网络程序中,当我们向套接字文件描述符写时有俩种可能。1)write的返回值大于0,表示写了部分或者是全部的数据。2)返回的值小于0,此时出现了错误。我们要根据错误类型来处理。如果错误为EINTR表示在写的时候出现了中断错误。如果为EPIPE表示网络连接出现了问题(对方已经关闭了连接)。
当然,使用这些函数之前,我们需要先定义一个context结构,具体使用例子如下:。newff函数参数列表有很多的可选参数,具体可以参考matlab的帮助文档,这里介绍newff函数的一种简单的形式。使用这个类的几个静态方法即可完成对报表的编译工作(具体参见api文档)。
4.6、close()函数
在服务器与客户端建立连接之后,会进行一些读写操作,完成了读写操作就要关闭相应的socket描述字,好比操作完打开的文件要调用fclose关闭打开的文件。
int close(int fd);
close一个TCP socket的缺省行为时把该socket标记为以关闭,然后立即返回到调用进程。该描述字不能再由调用进程使用,也就是说不能再作为read或write的第一个参数。
注意:close操作只是使相应socket描述字的引用计数-1,只有当引用计数为0的时候,才会触发TCP客户端向服务器发送终止连接请求。
服务器端:一直监听本机的8888号端口,如果收到连接请求,将接收请求并接收客户端发来的消息,并向客户端返回消息。
/*************************************************************************
> File Name: ser.c
> Author: battle
> Mail: batbattle@163.com
example:小明是民国六十八年八月三日下午五时生于彰化,那么她的恒星时间该是:〔8月×2(时)〕+〔3日×4(分)〕+4小时36分+〔17时(原出生时间二十四小时制)+1时(民国六十八年七月一日至九月三十日为日光节约时间)+2分8秒(与中原标准时时差)〕16时12分+4时36分+18时2分8秒=38时50分8秒(ps:超过24hr减24hr,所以小明的出生恒星时间为14时50分8秒)。例如:你的出生时间是阳历1940年12月22日1时30分,通过《万年历》查到出生时间点是处于二十四节气的“小雪”(阳历1940年11月22日18时48分55秒)与“冬至”(阳历1940年12月22日7时54分41秒)两个中气之间,便可知道你的太阳星座是属于射手座。例如:你的出生时间是阳历1958年4月20日17时53分,通过《万年历》查到出生时间点是处于二十四节气的“春分”(阳历1958年3月21日11时5分47秒)与“谷雨”(阳历1958年4月20日22时26分58秒)两个中气之间,便可知道你的太阳星座是属于白羊座。
到时要修改婚姻法