Linux Socket - 基本socket链接
0x0000 Linux Socket 函数
bind
listen
connect
accept
send
recv
read
write
0x0001
Server绑不上ip
报错位置在bind函数
[root@localhost 01]# ./server 191.168.80.151 1588
191.168.80.151 : 1588
Bind: Cannot assign requested address
port已被占用
报错位置在bind函数
[root@localhost 01]# ./server 192.168.80.151 1588
192.168.80.151 : 1588
Bind: Address already in use
没有这个网卡/端口号出不去
报错
Connect: No route to host
考虑自己防火墙是否挡住了这个端口
telnet 自己ip 端口
操作:
1. 关防火墙(不推荐)
2. 向防火墙添加这个端口放过的规则
recv后ctrl+c结束client

recv后在新窗口结束client

0x0002 Server接不上(端口号错、对方ip输错)
报错:
Connect: Network is unreachable
考虑Server防火墙是不是过不去
telnet 对方ip 端口
第二次接同一个Server端口
报错在Connect
[root@localhost 01]# ./client 192.168.80.151 1588
192.168.80.151 : 1588
Connect: Connection refused
接通后再杀死client
Server以非异常方式退出(不报error)
Client:
[root@localhost 01]# ./client 192.168.80.151 1588
192.168.80.151 : 1588
Connect: Success
Enter message to send:^Z
[1]+ 已停止 ./client 192.168.80.151 1588
[root@localhost 01]# ps
PID TTY TIME CMD
8114 pts/0 00:00:00 bash
11288 pts/0 00:00:00 client
11290 pts/0 00:00:00 ps
[root@localhost 01]# kill -9 11288
[root@localhost 01]#
Server:
[root@localhost 01]# ./server 192.168.80.151 1588
192.168.80.151 : 1588
Listening
Accept client 192.168.80.153
[root@localhost 01]#

接通后杀死Server
Client以正常方式退出(不报error)
Server:
[root@localhost 01]# ./server 192.168.80.151 1588
192.168.80.151 : 1588
Listening
Accept client 192.168.80.153
^C
[root@localhost 01]#
Client:
[root@localhost 01]# ./client 192.168.80.151 1588
192.168.80.151 : 1588
Connect: Success
Enter message to send:HelloServer
received:
Enter message to send:HelloServer
[root@localhost 01]#
0x0003 链接成功后从新会话启动Client

使用指定端口的方式在client和server上都用bind方法

Client3连接不存在的ip
[root@localhost 03]# ./tcp_client3 192.168.122.1
server_port: 192
server_ip: INADDR_ANY
client_port: 0
Connect: Network is unreachable
255.255.255.255:192
同一张网卡设置多个ip掩码都不在一个网段上能通才怪呢
0x0004 read write recv send
0x0004-1-1Read Write Test
read一旦读完一次缓冲就立刻返回,不能读满后返回
write读到的内容和client相同

0x0004-1-2延时write

0x0004-2-1Recv Send Test
recv 和send的主要区别是带有第四个参数能够对阻塞和非阻塞等信息进行控制
MSG_DONTROUTE | 不查找表 |
MSG_OOB | 接受或者发送带外数据 |
MSG_PEEK | 查看数据,并不从系统缓冲区移走数据 |
MSG_WAITALL | 等待所有数据 |
recv和send的结果与read write相同

0x0004-2-2延时send

0x0005
内核缓冲区测试
测试最大写入write后阻塞

netstat 命令及其参数
-a (all)显示所有选项,默认不显示LISTEN相关
-t (tcp)仅显示tcp相关选项
-u (udp)仅显示udp相关选项
-n 拒绝显示别名,能显示数字的全部转化成数字。
-l 仅列出有在 Listen (监听) 的服務状态
-p 显示建立相关链接的程序名
-r 显示路由信息,路由表
-e 显示扩展信息,例如uid等
-s 按各个协议进行统计
-c 每隔一个固定时间,执行该netstat命令。
提示:LISTEN和LISTENING的状态只有用-a或者-l才能看到
setsockopt 函数
设置套接口的选项。
#include <sys/types.h>
#include <sys/socket.h>
int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t optlen);
sockfd:标识一个套接口的描述字。
level:选项定义的层次;支持SOL_SOCKET、IPPROTO_TCP、IPPROTO_IP和IPPROTO_IPV6。
optname:需设置的选项。
optval:指针,指向存放选项待设置的新值的缓冲区。
optlen:optval缓冲区长度。
1.closesocket(一般不会立即关闭而经历TIME_WAIT的过程)后想继续重用该socket:
BOOL bReuseaddr=TRUE;
setsockopt(s,SOL_SOCKET ,SO_REUSEADDR,(const char*)&bReuseaddr,sizeof(BOOL));
2. 如果要已经处于连接状态的soket在调用closesocket后强制关闭,不经历
TIME_WAIT的过程:
BOOL bDontLinger = FALSE;
setsockopt(s,SOL_SOCKET,SO_DONTLINGER,(const char*)&bDontLinger,sizeof(BOOL));
3.在send(),recv()过程中有时由于网络状况等原因,发收不能预期进行,而设置收发时限:
int nNetTimeout=1000;//1秒
//发送时限
setsockopt(socket,SOL_S0CKET,SO_SNDTIMEO,(char *)&nNetTimeout,sizeof(int));
//接收时限
setsockopt(socket,SOL_S0CKET,SO_RCVTIMEO,(char *)&nNetTimeout,sizeof(int));
4.在send()的时候,返回的是实际发送出去的字节(同步)或发送到socket缓冲区的字节
(异步);系统默认的状态发送和接收一次为8688字节(约为8.5K);在实际的过程中发送数据
和接收数据量比较大,可以设置socket缓冲区,而避免了send(),recv()不断的循环收发:
// 接收缓冲区
int nRecvBuf=32*1024;//设置为32K
setsockopt(s,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));
//发送缓冲区
int nSendBuf=32*1024;//设置为32K
setsockopt(s,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));
5. 如果在发送数据的时,希望不经历由系统缓冲区到socket缓冲区的拷贝而影响
程序的性能:
int nZero=0;
setsockopt(socket,SOL_S0CKET,SO_SNDBUF,(char *)&nZero,sizeof(nZero));
6.同上在recv()完成上述功能(默认情况是将socket缓冲区的内容拷贝到系统缓冲区):
int nZero=0;
setsockopt(socket,SOL_S0CKET,SO_RCVBUF,(char *)&nZero,sizeof(int));
7.一般在发送UDP数据报的时候,希望该socket发送的数据具有广播特性:
BOOL bBroadcast=TRUE;
setsockopt(s,SOL_SOCKET,SO_BROADCAST,(const char*)&bBroadcast,sizeof(BOOL));
8.在client连接服务器过程中,如果处于非阻塞模式下的socket在connect()的过程中可
以设置connect()延时,直到accpet()被呼叫(本函数设置只有在非阻塞的过程中有显著的
作用,在阻塞的函数调用中作用不大)
BOOL bConditionalAccept=TRUE;
setsockopt(s,SOL_SOCKET,SO_CONDITIONAL_ACCEPT,(const char*)&bConditionalAccept,sizeof(BOOL));
9.如果在发送数据的过程中(send()没有完成,还有数据没发送)而调用了closesocket(),以前我们
一般采取的措施是"从容关闭"shutdown(s,SD_BOTH),但是数据是肯定丢失了,如何设置让程序满足具体
应用的要求(即让没发完的数据发送出去后在关闭socket)?
struct linger {
u_short l_onoff;
u_short l_linger;
};
linger m_sLinger;
m_sLinger.l_onoff=1;//(在closesocket()调用,但是还有数据没发送完毕的时候容许逗留)
// 如果m_sLinger.l_onoff=0;则功能和2.)作用相同;
m_sLinger.l_linger=5;//(容许逗留的时间为5秒)
setsockopt(s,SOL_SOCKET,SO_LINGER,(const char*)&m_sLinger,sizeof(linger));
使用setsockopt调整内核缓冲区的大小后
(不慎调的更小了)

0x0006
0x0006.1
两边都进入read阻塞状态,无法传送数据

0x0006.2
读写大小一致,可以正常传输
读写大小不一致,冗余的数据最后会堵住一边的write
(图相同,省略)

0x0006.3
前两种都是正常收发
(省略其他图片)

第三种 server 1000 1000 client 700 700
client完成了一轮write read server read都没有做完就阻塞了

0x0006.4
前两种都是正常收发
(同3)
第三种 server 1000 1000 client 700 700
client写完之后阻塞在read server read没有做完,阻塞

Linux Socket - 基本socket链接的更多相关文章
- Linux Kernel ‘/net/socket.c’本地信息泄露漏洞
漏洞名称: Linux Kernel ‘/net/socket.c’本地信息泄露漏洞 CNNVD编号: CNNVD-201312-037 发布时间: 2013-12-04 更新时间: 2013-12- ...
- Windows 和 Linux下使用socket下载网页页面内容(可设置接收/发送超时)的代码
主要难点在于设置recv()与send()的超时时间,具体要注意的事项,请看代码注释部分,下面是代码: #include <stdio.h> #include <sys/types. ...
- Windows下与Linux下编写socket程序的区别 《转载》
原文网址:http://blog.chinaunix.net/uid-2270658-id-308160.html [[Windows]] [Windows: 头文件的区别] #include< ...
- Linux C++ UDP Socket通信实例
环境:Linux 语言:C++ 通信方式:UDP 服务器端的步骤如下: 1. socket: 建立一个socket 2. bind: 将这个socket绑定在某个端口上(A ...
- Linux学习之socket编程(一)
socket编程 socket的概念: 在TCP/IP协议中,“IP地址+TCP或UDP端口号”唯一标识网络通讯中的一个进程,“IP地址+端口号”就称为socket. 在TCP协议中,建立连接的两个进 ...
- linux网络编程-socket(37)
在编程的时候需要加上对应pthread开头的头文件,gcc编译的时候需要加了-lpthread选项 第三个参数是线程的入口参数,函数的参数是void*,返回值是void*,第四个参数传递给线程函数的参 ...
- Linux 应用开发----socket编程笔记
Linux socket编程 套接字定义描述 套接字的域 AF_INET ====>IPv4 AF_INET6 ====>IPv6 AF_UNIX ====>unix 域 AF_UP ...
- Linux中查看socket状态(转)
Linux中查看socket状态:cat /proc/net/sockstat #(这个是ipv4的) sockets: used 137 TCP: inuse 49 orphan 0 tw 3272 ...
- 纯Socket(BIO)长链接编程的常见的坑和填坑套路
本文章纯属个人经验总结,伪代码也是写文章的时候顺便白板编码的,可能有逻辑问题,请帮忙指正,谢谢. Internet(全球互联网)是无数台机器基于TCP/IP协议族相互通信产生的.TCP/IP协议族分了 ...
- Linux网络编程--socket
1.socket的核心思想是,作为服务器间的进程间通信的最底层的实现,常用的大部分网络协议都是基于socket实现. 2.socket 是如何与最终的低层收发包建立联系的? 3.socket 是如何与 ...
随机推荐
- eclipse 创建dynamic web project不能运行
按照李刚<轻量级java ee企业应用实战>第三版,第二章的配置,发现eclipse 创建dynamic web project不能运行,原来作者第二章时还不是在eclipse中开发的,只 ...
- 详解jenkins几个有用的插件如何使用(emma,findbugs)
原文:http://myeyeofjava.iteye.com/blog/1765552 findbugs使用方式: 目的:进行代码走查的自动化,能够提示垃圾代码或者提供代码优化的建议 1.首先下载f ...
- 不用写代码就能实现深度学习?手把手教你用英伟达 DIGITS 解决图像分类问题
2006年,机器学习界泰斗Hinton,在Science上发表了一篇使用深度神经网络进行维数约简的论文 ,自此,神经网络再次走进人们的视野,进而引发了一场深度学习革命.深度学习之所以如此受关注,是因为 ...
- 项目管理工具maven(二)
2 整合ssh框架 2.1 依赖传递 只添加了一个struts2-core依赖,发现项目中出现了很多jar, 这种情况 叫 依赖传递 2.2 依赖版本冲突的解决 1. 第一声明优先原则 <dep ...
- 在VS2005编程中,有的时候DataGridView数据源有几个表的联合查询,而系统又有限制为一个表,怎么办?
在VS2005编程中,有的时候DataGridView数据源有几个表的联合查询,而系统又有限制为一个表,怎么办? 解决方法:在SqlServer的企业管理器里增加一个视图吧!!!!!!!!(从来没用过 ...
- XE: Changing the default http port
Oracle XE uses the embedded http listener that comes with the XML DB (XDB) to serve http requests. T ...
- 取消Eclipse的Error Reporting
选择Preferences->General->Error Reporting,Send Mode选择Never send reports
- eclipse cut copy paste plugin
The Cut Copy Paste Plus plug-in enhances the standard Cut, Copy and Paste commands in Eclipse IDE. W ...
- 《C语言基础日常笔记》
1. 类型转换-----------------20130902 a, 浮点数(包括单精度与双精度)赋值给整型变量时,舍弃浮点数的小数部分,直接将其整数部分存放在整型变量里. b, 整型变量赋值给浮点 ...
- Yosemite 给 iOS 录屏
[Yosemite 给 iOS 录屏] Mac 升级到Yosemite后,支持iOS屏幕录制.把Mac和iPhone用数据线相连.打开QuickTime Player,新建一个影片. 从摄像头源中选择 ...