linux send与recv函数详解www.cnblogs.com/blankqdb/archive/2012/08/30/2663859.html
1.端口被占用怎么办?
*通常都是服务器端口被占用,客户端系统会分配一个未被占用的端口给你与服务端固定的端口链接。
*1我们可以通过查看端口的命令看那些端口被占用,以避免使用这些端口。比如netstat命令查看网络连接。netstat -a inet
*2我们可以查看/etc/services系统配置文件中,查看系统所使用的服务和已经被使用的端口。以避免使用这些端口即可。
端口、服务器ip、协议tcp/udp. : 一下函数基本上调用成功返回0,调用失败返回-1,具体错误去errno中找即可。
防止connect(),accept()阻塞可以使用:fcntl(sockfd,F_SETFL,O_NONBLOCK|flags)来防止阻塞。
socket( AF_INET, SOCK_STREAM,0);0表示使用默认的ip协议。
bind(fd,struct_add,add_len);绑定ip,port.指定好长度别太短否则会截断你。/服务端绑定的时候,可以addr.sin_addr.s_addr = htonl(INADDR_ANY);;来表示接收任何机器的访问,如果指定一个ip或者一组ip就,仅仅限制与这些机器提供服务。
listen(fd,1000):创建1000个队列,最大等待数为1000个链接,再多就扔掉。
accpte(fd,client_add,add_len):需要给个空地址,用来接收客户端的信息,方便记录下来好发送回确认信息和返回具体消息过去。
recv() / read(fd,buf,size())
send()/ write(fd,buf,size())
close(fd)
对于服务器来说,当read()返回0时,就该关闭该条子socket连接了。
回路网络对于测试比较有用,因为他排除了一切的外部internet的网络问题,仅仅吧测试范围缩小到了程序本身和本机网卡本身。127.0.0.1
==================
在生成add地址结构体时,要将端口和ip转换成网络的字节序列,htonl() htons() .. host to network,long / short
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
server_address.sin_port = htons(1234);
inet_addr("127.0.0.1");//我们不需要对inet_addr地址做htonl()转换,因为inet_addr本身内部会转成网络序列。
=====================================
对于一个通用的c/s程序,我们应该使用网络信息函数来获取ip和port.而不是在程序中已经定好了。
/etc/server: getservbyname() , getservbyport();
/etc/hosts: gethostbyname() , gethostbyaddr(); inet_ntoa(in_addr);将ip转成字符形式。
例子程序,可以参考<linux程序设计第4版>
ps:/etc/services文件就是统一调配服务端口及服务协议的文件‘
/etc/host,主机名和IP配置文件,这2个文件可以配置主机ip及对应的主机名,对于服务器类型的linux系统其作用还是不可忽略的。
=====================================
xinetd/inetd 因特网守护进程: 其配置文件:/etc/xinetd.conf , /etc/xinetd.d目录下的文件。
由于许多服务不是很常用,所以我们用xinetd来统一监听其配置文件中的服务的端口,如果一旦有请求来到,则进行唤醒相应的服务程序来做服务。
有些请求需要启动外部服务程序称为外部,有些请求xinetd直接可以处理称为内部。type = internal
如果你要修改配置文件并让它生效,只需要killall xinetd进程即可。 然后再次启动xinetd即可生效。
=====================================
套接字选项:setsockopt(); 比如:*打开调试信息 *通过定期传输保持活报文来维持链接 *在close调用返回之前完成传输工作
*如果程序需要创建子进程的话,我们如果不需要等待子进程结束的话,可以忽略掉sigchld信号以避免出现僵尸进程。
fork():仅仅是拷贝同样的环境代码,在目前已经执行到的地方开始执行。而不是从头开始执行。
用fork来处理多个客户连接是不可行的,因为服务器的副本相当大岂不是很浪费资源,所以我们可以使用select()来调用。
======================================
select()调用允许程序同时在多个底层文件描述符上等待输入的到达。即:服务器可以通过同时在多个打开的套接字上等待请求到来的方法来处理多个客户的请求。
select对数据结构fd_set进程操作,它是由打开的文件描述符构成的集合。
宏:fd_zero(), fd_clr() , fd_set(),fd_isset(); fd_setsize指定了可以容纳的最大数目。
select( fd_setsize, readfds, writefds, errorfds, timeout防止阻塞的超时设定 )
*/: socket中send() recv()并非你发送几次,那边就recv几次,这个东西由Tcp来决定和控制,他里面有缓冲滴吗。
//////////////////////////////////////
1.CreateConnect();
2.SendData(); --> 可以在while()内部:自己定协议,可以分段send.
2.CloseConnect();
1.CreateThread();每个请求都创建个线程
2.RecvData(); --> 可以在线程内部的while()中循环获取,知道客户关闭链接,木有东东鸟。自己解协议,分段进行recv.
3.CloseConnect();
我那个程序,设置的buff分别为如下,所每秒传输的大小:
1. 1024*1024 10.6M/s
2. 1024*900 10.4M/s
3. 1024*800 8M/s
4. 1024*600 10.3M/s
5. 1024*512 10.3M/s
6. 1024*400 10.3M/s
7. 1024*64 9.3/s
8. 1024*300 10M/s
9.1024*200 9.5M/s
19.1024*100 9.8M/s
11. 1024*16 7.5M/s