2013-09-21 17:58:19 lijitaoccnu 阅读数 170
  • TCP/IP/UDP Socket通讯开发实战 适合iOS/Android/...

    本课程适合中学员,适用于从事iOS/Android/嵌入式Linux网络通讯开发的学员。实战案例可用于无人机,安防,直播等。从Linux音频,视频采集,到TCP/IP UDP Socket基础概念,网络编程接口介绍,POSIX线程封装,私有协议定义,开发,服务器模型,客户端编程等详细实战讲解,整个过程,涵盖iOS,Android ,Mac OS嵌入式Linux网络编程核心的大量实用场景。让学员能够掌握相关知识,融汇贯通掌握网络通讯开发核心知识。 付费学员加入QQ群,可获得本人未来1~3年学习过程中的专业指导解答。第三节课第7分15秒有QQ群,欢迎付费学员加入探讨技术问题。

    14726 人正在学习 去看看 陈超
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
TIME_WAIT 8947 等待足够的时间以确保远程TCP接收到连接中断请求的确认
FIN_WAIT1 15 等待远程TCP连接中断请求,或先前的连接中断请求的确认
FIN_WAIT2 1 从远程TCP等待连接中断请求
ESTABLISHED 55 代表一个打开的连接
SYN_RECV 21 再收到和发送一个连接请求后等待对方对连接请求的确认
CLOSING 2 没有任何连接状态
LAST_ACK 4 等待原来的发向远程TCP的连接中断请求的确认

TCP连接状态详解
LISTEN: 侦听来自远方的TCP端口的连接请求
SYN-SENT: 再发送连接请求后等待匹配的连接请求
SYN-RECEIVED:再收到和发送一个连接请求后等待对方对连接请求的确认
ESTABLISHED: 代表一个打开的连接
FIN-WAIT-1: 等待远程TCP连接中断请求,或先前的连接中断请求的确认
FIN-WAIT-2: 从远程TCP等待连接中断请求
CLOSE-WAIT: 等待从本地用户发来的连接中断请求
CLOSING: 等待远程TCP对连接中断的确认
LAST-ACK: 等待原来的发向远程TCP的连接中断请求的确认
TIME-WAIT: 等待足够的时间以确保远程TCP接收到连接中断请求的确认
CLOSED: 没有任何连接状态
2012-05-03 16:59:44 PerfTest 阅读数 3364
  • TCP/IP/UDP Socket通讯开发实战 适合iOS/Android/...

    本课程适合中学员,适用于从事iOS/Android/嵌入式Linux网络通讯开发的学员。实战案例可用于无人机,安防,直播等。从Linux音频,视频采集,到TCP/IP UDP Socket基础概念,网络编程接口介绍,POSIX线程封装,私有协议定义,开发,服务器模型,客户端编程等详细实战讲解,整个过程,涵盖iOS,Android ,Mac OS嵌入式Linux网络编程核心的大量实用场景。让学员能够掌握相关知识,融汇贯通掌握网络通讯开发核心知识。 付费学员加入QQ群,可获得本人未来1~3年学习过程中的专业指导解答。第三节课第7分15秒有QQ群,欢迎付费学员加入探讨技术问题。

    14726 人正在学习 去看看 陈超

对发送https请求进行性能测试,大量tcp连接处于time_wait状态。修改linux内核参数,发现只是对http起作用,对Https未起到作用。

https tcp time_wait属于系统环境的问题。在带宽为1000兆的网络环境中,造成网络传输的处理高于服务器对Https的处理能力。从而出现https  tcp time_wait。
以LoadRuner降低带宽测试,在100兆的网络环境中,https TCP  time_wait出现率几乎为0。



Linux 内核 参数修改如下:


et.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 1
net.ipv4.tcp_max_tw_buckets = 6000
net.core.netdev_max_backlog = 262144
net.ipv4.tcp_max_syn_backlog = 262144


2016-09-12 17:18:20 qq_14976351 阅读数 370
  • TCP/IP/UDP Socket通讯开发实战 适合iOS/Android/...

    本课程适合中学员,适用于从事iOS/Android/嵌入式Linux网络通讯开发的学员。实战案例可用于无人机,安防,直播等。从Linux音频,视频采集,到TCP/IP UDP Socket基础概念,网络编程接口介绍,POSIX线程封装,私有协议定义,开发,服务器模型,客户端编程等详细实战讲解,整个过程,涵盖iOS,Android ,Mac OS嵌入式Linux网络编程核心的大量实用场景。让学员能够掌握相关知识,融汇贯通掌握网络通讯开发核心知识。 付费学员加入QQ群,可获得本人未来1~3年学习过程中的专业指导解答。第三节课第7分15秒有QQ群,欢迎付费学员加入探讨技术问题。

    14726 人正在学习 去看看 陈超

1.TCP网络编程架构

    TCP网络编程有两种模式,一种是服务器模式,另一种是客户端模式。服务器模式是通过建立一个服务监听客户端连接,当服务器收到客户端连接请求后,对请求进行处理;客户端模式是通过绑定服务器IP地址和端口,向服务器发送连接请求,并对服务器响应做出相应的处理。下图为TCP网络编程两种模式的架构图。

1  socket()介绍
  1. int socket(int domain,int type,int protocol)
domain 是用来设置网络通信域的,也就是选择你所采用的协议族。如,AF_INET代表ipv4,AF_INET6代表ipv6.
type 是用来设置套接字通信类型的。常用的类型有SOCK_STREAM(流式套接字)支持TCP连接,提供可靠的、序列化的、双向的字节流;SOCK_DGRAM(数据包套接字),支持UPD连接,无连接不可靠。
protocol 使用来指定type类型中的某个类型。通常某个协议只有一个特定的类型,这样protocol设置为0;但是,也有默写协议不止一个特定类型,使用这个协议时,就需要指明所使用协议的具体特定类型。
socket 函数通过以上三个参数最终生成一个套接字文件描述符。
  1. int sockfd = socket(AF_INET,SOCK_STREAM,0);
2 bind()介绍
  1. int bind(int sockfd,const struct sockaddr *myaddr,socklen_t addrlen);
首先介绍一下结构体sockaddr
  1. struct sockaddr{
  2. sa_family_t sa_family;//协议族
  3. char sa_data[14];//协议族数据
  4. }
其中,sa_family_t类型其实就是unsigned short类型;
接下来介绍bind函数中参数:
sockfd 为套接字文件描述符;
myaddr 为指向套接字地址结构的指针。在进行sockfd绑定的时候,需要将IP地址,端口、协议类型等信息进行绑定。而sockaddr结构体不方便设置,所以在以太网中,一般采用结构体struct sockaddr_in进行设置:
  1. struct sockaddr_in{
  2. u8 sin_len; //结构体长度
  3. u8 sin_family; //采用的协议族
  4. u16 sin_port; //端口号,网络字节序
  5. struct in_addr sin_addr; //IP地址32bits
  6. char sin_zero[8]; //未用
  7. }
结构体struct sockaddr 和结构体 struct sockaddr_in 大小相同,两者可以相互转化。可以说,struct sockaddr_instruct sockaddr的细化。addrlen 是myaddr的长度,addrlen = sizeof(struct sockaddr);
3 listen()介绍
  1. int listen(int sockfd,int backlog);
在接受一个连接之前,需要使用listen来监听端口,backlog表示在accept()函数处理之前在等待队列中的客户端长度。
4 accept()介绍
当一个客户端请求到达服务器所监听的端口后,服务器会将此时的客户端请求加入到客户端等待队列中,直到使用accept()处理请求。accept()成功执行后,会返回一个客户端的套接字文件描述符,客户端的信息可以通过这个描述符来获得。
  1. int accept(int sockfd,struct sockaddr *addr,socklen_t *addrlen);
其中,根据addr可以获得IP、端口、协议类型等信息。 这里需要注意的是,addlen是一个指针,accept将其传给TCP/IP协议栈。
 5 connect()介绍
客户端在建立套接字后,不需要绑定IP,端口等信息。客户端通过connect()函数连接服务器,connect()中指定了服务器IP地址、目的端口等信息。
  1. int connect(int sockfd,struct sockaddr *, int addrlen);
6 write()介绍
当服务器收到一个客户端连接后,通过套接字描述符来进行数据写入。
  1. int size = write(s,data,1024);
将data中的数据全部写入s中,返回值为成功写入的数据长度。
7 客户端服务器实现代码:
服务器代码:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <sys/types.h>
  5. #include <sys/socket.h>
  6. #include <arpa/inet.h>
  7. #include <unistd.h>
  8. #define PORT 8888 /*侦听端口地址*/
  9. #define BACKLOG 2 /*侦听队列长度*/
  10. int main(int argc, char *argv[])
  11. {
  12. int ss,sc; /*ss为服务器的socket描述符,sc为客户端的socket描述符*/
  13. struct sockaddr_in server_addr; /*服务器地址结构*/
  14. struct sockaddr_in client_addr; /*客户端地址结构*/
  15. int err; /*返回值*/
  16. pid_t pid; /*分叉的进行ID*/
  17. /*建立一个流式套接字*/
  18. ss = socket(AF_INET, SOCK_STREAM, 0);
  19. if(ss < 0){ /*出错*/
  20. printf("socket error\n");
  21. return -1;
  22. }
  23. /*设置服务器地址*/
  24. bzero(&server_addr, sizeof(server_addr)); /*清零*/
  25. server_addr.sin_family = AF_INET; /*协议族*/
  26. server_addr.sin_addr.s_addr = htonl(INADDR_ANY); /*本地地址*/
  27. server_addr.sin_port = htons(PORT); /*服务器端口*/
  28. /*绑定地址结构到套接字描述符*/
  29. err = bind(ss, (struct sockaddr*)&server_addr, sizeof(server_addr));
  30. if(err < 0){/*出错*/
  31. printf("bind error\n");
  32. return -1;
  33. }
  34. /*设置侦听*/
  35. err = listen(ss, BACKLOG);
  36. if(err < 0){ /*出错*/
  37. printf("listen error\n");
  38. return -1;
  39. }
  40. /*主循环过程*/
  41. for(;;) {
  42. socklen_t addrlen = sizeof(struct sockaddr);
  43. sc = accept(ss, (struct sockaddr*)&client_addr, &addrlen);
  44. /*接收客户端连接*/
  45. if(sc < 0){ /*出错*/
  46. continue; /*结束本次循环*/
  47. }
  48. /*建立一个新的进程处理到来的连接*/
  49. pid = fork(); /*分叉进程*/
  50. if( pid == 0 ){ /*子进程中*/
  51. process_conn_server(sc); /*处理连接*/
  52. close(ss); /*在子进程中关闭服务器的侦听*/
  53. }else{
  54. close(sc); /*在父进程中关闭客户端的连接*/
  55. }
  56. }
  57. }
客户端代码:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <sys/types.h>
  5. #include <sys/socket.h>
  6. #include <unistd.h>
  7. #include <arpa/inet.h>
  8. #define PORT 8888 /*侦听端口地址*/
  9. int main(int argc, char *argv[])
  10. {
  11. int s; /*s为socket描述符*/
  12. struct sockaddr_in server_addr; /*服务器地址结构*/
  13. s = socket(AF_INET, SOCK_STREAM, 0); /*建立一个流式套接字 */
  14. if(s < 0){ /*出错*/
  15. printf("socket error\n");
  16. return -1;
  17. }
  18. /*设置服务器地址*/
  19. bzero(&server_addr, sizeof(server_addr)); /*清零*/
  20. server_addr.sin_family = AF_INET; /*协议族*/
  21. server_addr.sin_addr.s_addr = htonl(INADDR_ANY); /*本地地址*/
  22. server_addr.sin_port = htons(PORT); /*服务器端口*/
  23. /*将用户输入的字符串类型的IP地址转为整型*/
  24. inet_pton(AF_INET, argv[1], &server_addr.sin_addr);
  25. /*连接服务器*/
  26. connect(s, (struct sockaddr*)&server_addr, sizeof(struct sockaddr));
  27. process_conn_client(s); /*客户端处理过程*/
  28. close(s); /*关闭连接*/
  29. return 0;
  30. }
完整代码见http://download.csdn.net/detail/qq_14976351/9630793
2018-06-08 09:34:01 qq_24243483 阅读数 95
  • TCP/IP/UDP Socket通讯开发实战 适合iOS/Android/...

    本课程适合中学员,适用于从事iOS/Android/嵌入式Linux网络通讯开发的学员。实战案例可用于无人机,安防,直播等。从Linux音频,视频采集,到TCP/IP UDP Socket基础概念,网络编程接口介绍,POSIX线程封装,私有协议定义,开发,服务器模型,客户端编程等详细实战讲解,整个过程,涵盖iOS,Android ,Mac OS嵌入式Linux网络编程核心的大量实用场景。让学员能够掌握相关知识,融汇贯通掌握网络通讯开发核心知识。 付费学员加入QQ群,可获得本人未来1~3年学习过程中的专业指导解答。第三节课第7分15秒有QQ群,欢迎付费学员加入探讨技术问题。

    14726 人正在学习 去看看 陈超

Linux网络 - tcp三次握手-四次挥手

###

一、术语解释

ACK: 一种传输类的确认控制字符。接收方成功地接收到数据,那么会回复对方一个ACK数据,TCP协议规定,只有ACK=1时有效,也规定连接建立后所有发送的报文的ACK必须为1

SYN:  在连接建立时用来同步序号。当SYN=1ACK=0时,表明这是一个连接请求报文,对方若同意建立连接,则应在响应报文中使SYN=1ACK=1,因此,  SYN1就表示这是一个连接请求或连接接受报文。

FIN: 用来释放一个连接。当 FIN = 1 时,表明此报文段的发送方的数据已经发送完毕,并要求释放连接。

seq: TCP连接是面向字节流的,seq标识某一方发送数据的字节序号(mod 2^32),整个连接中,字节流的起始序号在建立连接时设置,一个报文段的数据包一般会包含多个字节的数据,以数据包第一个字节的序号标识报文段序号。

ack: 下一个期望接收的数据包的序号。


二、建立连接 - 三次握手

2.1. 示意图

1: SYN=1, seq=x,ACK=0

2: SYN=1, ACK=1,seq=y, ack=x+1

3: ACK=1,seq=x+1, ack=y+1

2.2. 需要第三次握手的目的


三、释放连接 - 四次挥手

3.1. 示意图


1: FIN=1, seq=u

2: ACK=1, seq=v, ack=u+1

3: FIN=1, ACK=1, seq=w, ack=u+1

4: ACK=1, seq=u+1, ack=w+1

3.2. TIME_WAIT的作用

     TIME_WAIT作用:  2ms,假如ActiveCloser发送的确认释放连接信息PassiveCloser没有收到,这时候P会再次发送一个FIN=1的释放连接报文,而这个时候A还处于TIME-WAIT,所以可以再次发送确认信息。


【参考链接】

https://blog.csdn.net/oney139/article/details/8103223

https://www.cnblogs.com/xiaoming0601/p/6001021.html

https://blog.csdn.net/jewes/article/details/52654997



2018-08-11 17:15:53 xutong98 阅读数 543
  • TCP/IP/UDP Socket通讯开发实战 适合iOS/Android/...

    本课程适合中学员,适用于从事iOS/Android/嵌入式Linux网络通讯开发的学员。实战案例可用于无人机,安防,直播等。从Linux音频,视频采集,到TCP/IP UDP Socket基础概念,网络编程接口介绍,POSIX线程封装,私有协议定义,开发,服务器模型,客户端编程等详细实战讲解,整个过程,涵盖iOS,Android ,Mac OS嵌入式Linux网络编程核心的大量实用场景。让学员能够掌握相关知识,融汇贯通掌握网络通讯开发核心知识。 付费学员加入QQ群,可获得本人未来1~3年学习过程中的专业指导解答。第三节课第7分15秒有QQ群,欢迎付费学员加入探讨技术问题。

    14726 人正在学习 去看看 陈超

概念:

TCP网络编程有两种模式,一种是服务器模式,另一种是客户端模式

(1)服务器模式创建一个服务程序,等待客户端用户的连接,接收到用户的连接请求后,根据用户的请求进行处理;

(2)客户端模式则根据目的服务器的地址和端口进行连接,向服务器发送请求并对服务器的响应进行数据处理。

服务器端的程序设计模式:

流程主要分为

(1)套接字初始化(socket()

(2)套接字与端口的绑定(bind()

(3)设置服务器的侦听连接(listen()

(4)接受客户端连接(accept()

(5)接收和发送数据(read()write()

(6)并进行数据处理及处理完毕的套接字关闭(close())。

客户端的程序设计模式:

客户端模式分为

(1)套接字初始化(socket()

(2)连接服务器(connect()

(3)读写网络数据(read()write()

(4)并进行数据处理和最后的套接字关闭(close())。

客户端与服务器的交互过程:

客户端与服务器在连接、读写数据、关闭过程中有交互过程。

函数介绍: 

1、socket()函数介绍

如果函数调用成功,会返回一个表示这个套接字的文件描述符,失败的时候返回–1

#include <sys/types.h>

#include <sys/socket.h>

int socket(int domain, int type, int protocol);

(1)domain即协议域,又称为协议族(family),AF_INET

(2)type指定socket类型。

      常用的socket类型有:SOCK_STREAMSOCK_DGRAMSOCK_RAWSOCK_PACKETSOCK_SEQPACKET等。

(3)protocol:故名思意,就是指定协议,一般设置为0

举例:int sock=socket(AF_INET,SOCK_STREAM,0)

2、绑定一个地址端口对bind()

在服务器设计中,建立套接字文件描述符成功后,需要对套接字进行地址和端口的绑定,才能进行数据的接收和发送操作。

bind()函数介绍

bind()函数将长度为addlenstruct sockadd类型的参数my_addrsockfd绑定在一起,将sockfd绑定到某个端口上。

绑定的函数原型如下:

#include <sys/types.h>

#include <sys/socket.h>

int bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen);

3、接受一个网络请求accept()

当一个客户端的连接请求到达服务器主机侦听的端口时,此时客户端的连接会在队列中等待,直到使用服务器处理接收请求。

函数accept()成功执行后,会返回一个新的套接字文件描述符来表示客户端的连接,客户端连接的信息可以通过这个新描述符来获得。

accept()函数的原型如下:

#include <sys/types.h>

#include <sys/socket.h>

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

 第一个参数为服务器的socket描述字

第二个参数为指向struct sockaddr *的指针,用于返回客户端的协议地址 

第三个参数为指向协议地址长度指针。

如果accpet成功,那么其返回值是由内核自动生成的一个全新的描述字,代表与返回客户的TCP连接;否则返回-1

注意:

1.accept的第一个参数为服务器的socket描述字,是服务器开始调用socket()函数生成的,称为监听socket描述字,一个服务器通常仅仅只创建一个监听socket描述字,它在该服务器的生命周期内一直存在。

2.accept函数返回的是已连接的socket描述字。内核为每个由服务器进程接受的客户连接创建了一个已连接socket描述字,当服务器完成了对某个客户的服务,相应的已连接socket描述字就被关闭。

4、连接目标网络服务器connect()

客户端在建立套接字之后,不需要进行地址绑定就可以直接连接服务器。连接服务器的函数为connect(),此函数连接指定参数的服务器,例如IP地址、端口等。

connect()函数的原型如下。

#include <sys/types.h>

#include <sys/socket.h>

int connect(int sockfd, struct sockaddr* addr, int addrlen);

基于TCP协议的客户端服务器:

客户端:

//TCPclient.c
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include<pthread.h>
#include<string.h>
#include<arpa/inet.h>
#define PORT 8000

int main()
{
	int sockfd , ret;
	struct sockaddr_in server_addr;
	char buf[32] = {0};
	
	sockfd = socket(PF_INET , SOCK_STREAM , 0);   //创建一个socket
	if(sockfd == -1)
	{
		perror("socket");
		exit(1);
	}
	
	int length = sizeof(server_addr);
	//bind的参数 第二个是结构体  下面是结构体
	server_addr.sin_family = PF_INET;    //PF_INET 地址族
	server_addr.sin_port = PORT;         //端口号
	server_addr.sin_addr.s_addr = inet_addr("192.168.1.10");   //写服务器地址
	
	ret = connect(sockfd , (struct sockaddr *)&server_addr , length);
	if(-1 == ret)
	{
		perror("connect");
		exit(1);
	}
	
	
	while(1)
	{		
		scanf("%s", buf);
		ret = send(sockfd , buf , strlen(buf) , 0);
		if(-1 == ret)
		{
			perror("send");
		}
		memset(buf , 0 ,sizeof(buf));
	}
	
	return 0;
}

服务器:

//TCPserver.c
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include<pthread.h>
#include<string.h>
#define PORT 8000

void *ClientHandle(void *arg)
{
	pthread_detach( pthread_self() );           //线程分离
	
	int ret;
	int fd = *(int *)arg;
	char buf[32]={0};
	
	ret = recv(fd , buf , sizeof(buf) , 0);
	if(-1 == ret)
	{
		perror("recv");
	}
	
	printf("recv from %d client %s!\n" , fd , buf);
	memset(buf , 0 , sizeof(buf) );
}

int main()
{
	int sockfd,ret;
	struct sockaddr_in server_addr;
	struct sockaddr_in client_addr;
	int fd[1000] = {0} , i=0;
	pthread_t tid;
	
	//采用IPV4协议 流式套接字
	sockfd = socket(PF_INET , SOCK_STREAM , 0);   //创建一个socket
	if(-1 == sockfd)
	{
		perror("socket");
		exit(1);
	}
	
	
	int length = sizeof(server_addr);
	//bind的参数 第二个是结构体  下面是结构体
	server_addr.sin_family = PF_INET;    //PF_INET 地址族
	server_addr.sin_port = PORT;         //端口号
	server_addr.sin_addr.s_addr = inet_addr("192.168.1.10");   //ip地址
	
	ret = bind(sockfd , (struct sockaddr *)&server_addr , length);  //绑定
	if(-1 == ret)
	{
		perror("bind");
		exit(1);
	}
	
	
	ret = listen(sockfd ,5);         //监听
	if(-1 == ret)
	{
		perror("listen");
		exit(1);
	}
	
	
	while(1)
	{
		memset( &client_addr , 0 , sizeof(client_addr) );
		fd[i] = accept(sockfd , (struct sockaddr *)&client_addr , &length);
		if(-1 == fd[i])
		{
			perror("accept");
			exit(1);
		}
		
		
		printf("accept client port %d fd %d\n",client_addr.sin_port,fd[i]);
		//加线程  循环一次就创建一个线程    线程id  属性内容  函数名  &fd[i]
		ret = pthread_create(&tid , NULL , ClientHandle , &fd[i]);
		if(ret != 0)
		{
			perror("pthread_create");
		}
		i++;
		
		//等待线程结束 回收资源 但是会阻塞
		//pthread_join();
	}	
		
	
	return 0;
}

 

 

基于Linux下的TCP编程

阅读数 29080

没有更多推荐了,返回首页