TCP/IP :
      TCP/IP:在网络通信中,TCP/IP是主流协议()
      应用层:用户自定义的协议(HTTP,EMAIL,),用于用户之间数据的传送
      传输层:(传输控制:TCP,UDP)负责点对点之间连接建立,传输控制协议的指定() 
      网络层:用于查找路由(查找)
      网络接口层 : 将二进制转换为数据帧。

TCP帧:
   [源端号][目的端口]     
   [   顺序号       ]
   [TCP包头长][URG/ACK/PSH/RST/SYN/FIN][窗口大小]
   [检验和][紧急指针]
   [可选项          ]
   [数据包]

TCP:面向连接,安全可靠有状态的传输协议。(比UDP效率差)
           怎样连接:三次握手简述(确保双方一定同时在线)
           A与B建立TCP连接时:首先A向B发SYN(同步请求)
                                                然后B回复SYN+ACK(同步请求应答)
                                                最后A回复ACK确认
           这样TCP的一次连接(三次握手)的过程就建立了!

/**** 下面部分转载自 : https://blog.csdn.net/sssnmnmjmf/article/details/68486261

TCP握手协议详述 :
           在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接.
           第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
           SYN:同步序列编号(Synchronize Sequence Numbers)
           第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;                                                                                                                                                                      第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手.
           完成三次握手,客户端与服务器开始传送数据

          所谓三次握手(Three-Way Handshake)即建立TCP连接,就是指建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立。在socket编程中,这一过程由客户端执行connect来触发,整个流程如下图所示:

TCP 服务器/客户端-LMLPHP

(1)第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。                                                                                                                                                                  (2)第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。                    (3)第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。                
         SYN攻击:
         在三次握手过程中,Server发送SYN-ACK之后,收到Client的ACK之前的TCP连接称为半连接(half-open connect),此时Server处于SYN_RCVD状态,当收到ACK后,Server转入ESTABLISHED状态。SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server回复确认包,并等待Client的确认,由于源地址是不存在的,因此,Server需要不断重发直至超时,这些伪造的SYN包将产时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络堵塞甚至系统瘫痪。SYN攻击时一种典型的DDOS攻击,检测SYN攻击的方式非常简单,即当Server上有大量半连接状态且源IP地址是随机的,则可以断定遭到SYN攻击了,使用如下命令可以让之现行:                
                                                                #netstat -nap | grep SYN_RECV

                                                                                                                                                     上面转载到此处结束 ****/

TCP通信:
       服务器:
              1、创建套接字(打开设备)
                    socket
              2、绑定
                    bind
              3、监听:(设置最大的可连接的线路的数量)
                    listen
              4、等待连接:是一个阻塞函数(注:执行一该函数,则连接一次)
                    int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
                   返回一个套接字,用于在此套接字上收发消息
              5、收到消息
                    recv
              6、关闭套接字                                                                                                                                                                                    注:由于accept和recv都需要阻塞等待,accept返回新的连接描述符。
                      为每一个新的连接请求分配一个新的进程或线程

        客户端:
               1、创建套接字(打开设备)
               2、绑定套接字
               3、发出连接请求
                    connect
               4、收发消息
                    send
                    recv
               5、关闭请求
                    close
        传输层:UPD报文SOCK_DGRAM    TCP:流式套接字SOCK_STREAM

        注:由于套接字上绑定有端口号,为了防止复用端口号,套接字默认不允许复用
        API:设备套接字  ---->  setsockopt ( int sock,int level ) ;  level:SOL_SOCKET  对套接字进行设置                                                  socklen_t len=1 ;
        if ( setsockopt ( sock,SOL_SOCKET,SO_REUSEADDR,&len,sizeof(len) ) <0 )
        {
                 perror ( "setsocket fail" ) ;
                 return -1 ;
        }

   TCP 服务器的代码实现 :

#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<pthread.h>
//创建锁
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
//子线程:接收链路信息
void* threadfun(void* arg)
{
	int sock=*(int*)arg;
//解锁
	pthread_mutex_unlock(&mutex);
//接收消息
	char buf[100]="";
	int ilen=0;
	while(1)
	{
		ilen=recv(sock,buf,99,0);
		if(ilen<=0)
			break;
		buf[ilen]='\0';
		printf("收到:%s\n",buf);
	}
	close(sock);
}
//TCP:流式套接字
int main()
{
//1创建套接字---打开设备
	int sock=socket(AF_INET,SOCK_STREAM,0);
	if(sock<0)
	{
		perror("socket fail");
		return -1;
	}
//修改套接字的网络层:允许IP复用
	socklen_t len=1;
	if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&len,sizeof(len))<0)
	{
		perror("setsocket fail");
		return -1;
	}
//2填充结构体并绑定
	struct sockaddr_in myaddr;	//7979;
	memset(&myaddr,0,sizeof(myaddr));
	myaddr.sin_family		=AF_INET;
	myaddr.sin_port			=htons(7979);
	myaddr.sin_addr.s_addr		=INADDR_ANY;

	if(bind(sock,(struct sockaddr*)&myaddr,sizeof(myaddr))==-1)
	{
		perror("bind fail");
		return -1;
	}
//3监听:设置最大的可连接数量,并监听
	listen(sock,44);
//4等待连接 accept
	int newsock=-1;
	pthread_t tid;
	while(1)
	{
		//上锁
		pthread_mutex_lock(&mutex);
		newsock=accept(sock,NULL,NULL);
		if(-1==newsock)
			break;
		//创建线程--函数
		pthread_create(&tid,NULL,threadfun,&newsock);
		//cout<<"有人连接我了\n"<<endl;
	}
/*
//5等待该链路上消息到来
	char buf[100]="";
	recv(newsock,buf,99,0);
	printf("收到:%s\n",buf);
*/
//6关闭
	close(sock);
	return 0;
}

   TCP 客户端的代码实现 : 

#include<stdio.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<string.h>
int main()
{
//1创建套接字
	int sock=socket(AF_INET,SOCK_STREAM,0);    //SOCK_STREAM 流氏sock
//2[绑定:系统为该套接字默认绑定一个空的端口号和一个网卡地址]
//3主动发出连接请求
	/*填充连接服务器的IP信息*/
	struct sockaddr_in saddr;
	memset(&saddr,0,sizeof(saddr));	//填充为0
	saddr.sin_family		=AF_INET;
	saddr.sin_port			=htons(7979);
	saddr.sin_addr.s_addr		=inet_addr("192.168.8.209");
	if(connect(sock,(struct sockaddr*)&saddr,sizeof(saddr))<0)    //连接
	{
		perror("connect fail");
		return -1;
	}
//4收发消息
	char buf[100]="";
	while(1)
	{
		scanf("%s",buf);        //客户端可以连续的发送内容
		send(sock,buf,strlen(buf),0);//strlen 求字符串的长度
	}
//5关闭
	close(sock);
}

 

10-03 16:02