网络编程整理

网络编程

1.TCP/UDP特点

1.TCP

1.面向连接(流式套接字 SOCK_STREAM)

2.数据完整安全,可靠,有序

PS:数据完整不丢失,有序 ,数据完整采用CRC循环冗余校验,数据不丢失采用重传机制和超时机制,有序的发送端的拆分编号,接收端排序组合。若在某一段时间内接收端到的为两个一样的数据,则选择丢弃其中的一个。发送者每发送一个tcp段,启动一个定时器,超时没有收到ACK,则重发。而接受者每收到一个tcp段,则发送一个ACK消息。

3.慢 (效率低,传输慢)

2.UDP

1.面向数据报(数据报套接字 SOCK_DGRAM)

2.数据可能会丢失,乱序

3.快

流式套接字:

1.数据无界限 (连续发送的多个数据之间无界限)

数据报套接字:

1.数据有明确界限

PS:针对流式套接字存在的数据之间无界限的问题要解决的方法:

场景建立:如果发送一个文件,首先要发送的是文件名,文件大小,文件内容。例如

if(writen(connfd,FILENAME,LEN_FILENAME)<0)

ERR("write failed");

//这儿的文件名为字符串,是属于字符数组,char[]无需转为网络序。

int filesize_nbo = htonl(filesize);

if(writen(connfd,&filesize_nbo,LEN_FILESIZE)<0)

ERR("write failed");

看网络状况,状况好的情况下,发送的快,则其中间隔较大,若网络不好的情况下,第二次与第一次的间隔较小,都将视为第一次发送的东西。解决办法,规定LEN_FILENAME,LEN_FILESIZE,即使文件名放不满,也要写LEN_FILENAME的这么多的数据过去。这时就要采用writen 保证确实写了如此多的数据过去。保证数据完整性。

2.网络中的数据传输

预备知识:字节序(大小端)

大端(big-endian):高地址>>>>低字节  低地址>>>高字节

小端(little--endian):高地址>>>高字节 低地址>>>低字节

1.单字节数据(char,char[],)

2.多字节数据(short,int,long)

发送之前:HBO(host byteorder) --> NBO(network byteorder)

接收之后:NBO --> HBO

htonl 32bit

ntohs 16bit

ntohl 32bit

3.结构体数据

1.成员要进行字节序转换

2.强制按照1字节补齐(即为不补齐) 加入push pop将结构体限制为push pop的范围之内。

#pragma pack (push)

#pragma pack (1)

struct A{

int a;

char c;

short b;

};

#pragma pack (pop)

struct B{};

4.浮点型数据的发送

整数,小数分开发

5.负数

整数

负数符号单独发

3.地址的表示方法(IP + Port)

IP

ipv4(32bit)/ipv6(128bit)

表示法:

字符串  "192.168.2.100"

数字 192<<24 | 168<<16 | 2<<8 | 100;

struct in_addr

{

in_addr_t s_addr; //NBO

};

可以用这种方法赋值:in_addr.s_addr=192<<24|168<<16|2<<8|100

inet_ntop();

inet_pton();

PORT

16bit(0-65535)  htons来将转化为网络序

0-1023 //周知端口,特权端口(只有root权限才能使用)

1023-

IPV4地址结构

struct sockaddr_in

{

sin_family_t sin_family //地址族(ipv4 or ipv6)

unsigned short sin_port //NBO 端口

struct in_addr sin_addr //NBO IP

char sin_zero[8] //保留

};

struct sockaddr_in6

{

//...

};

//通用地址结构

struct sockaddr

{

};

4.TCP编程

SOCK_STREAM(一般专指TCP)

SOCK_DGRAM (一般专指UDP)

SOCK_RAW(原始套接字,用以访问底层接口)

协议可以使用getprotobyname获取协议值,socket(PF_INET,SOCK_STREAM,0)其中0为协议值。默认为0仅限于TCP UDP,原始套接字编程要使用这个函数获得协议值。

1.服务器端

1.创建socket

socket

2.绑定地址

bind

3.监听

listen

while(1)

{

4.接收连接(阻塞)

accept

5.通信(多进程,多线程等模型)

read/write

6.关闭与当前客户端的连接

close/shutdown

}

7.关闭服务器

2.客户端

1.创建socket

socket

2.和对方建立连接

connect

3.通信

read/write

4.关闭连接

close/shutdown

5.udp编程

1.服务器端

1.创建socket

socket(PF_INET,SOCK_DGRAM,0);

2.绑定地址

bind(sockfd,(struct sockaddr*)&ipv4,sizeof(ipv4));

3.交互

read/write

sendto(sockfd,buf,size,0,const (struct sockaddr*)&peer,sizeof(peer))

recvfrom(sockfd,buf,size,0,struct sockaddr*,socklen_t *len)

4.关闭

close

2.客户端

1.创建socket

socket(PF_INET,SOCK_DGRAM,0);

2.绑定地址(可选)

bind(sockfd,(struct sockaddr*)&ipv4,sizeof(ipv4));

3.交互

read/write

sendto(sockfd,buf,size,0,const (struct sockaddr*)&peer,sizeof(peer))

recvfrom(sockfd,buf,size,0,struct sockaddr*,socklen_t *len)

4.关闭

close

数据有明确界限

5.udp广播

1.IP地址

网络号 + 主机号

网络号 + 子网号 + 主机号

2.广播地址

1.受限广播地址(所有路由器都不会转发目标为4个255的数据)

255.255.255.255

A

B

C

D

E

2.网内广播

子网号,主机号 全为1

3.子网内广播

主机号全为1

192.168.3.10/28的广播地址:192.168.3.15

3.广播编程

1.设置允许发送广播消息

setsockopt(int sockfd,int level,int optname,void *val,size_t len);

int val = 1;

setsockopt(sockfd,SOL_SOCKET,SO_BROADCAST,&val,sizeof(val));

2.发送目标地址为广播地址

6.udp组播

组播地址:

D类IP 224.0.0.1~239.255.255.255

1.发送者

发给一个组播地址

2.接收者(组播编程主要对接受者有限定)

1.加入组

struct ip_mreq{

struct in_addr imr_multiaddr;   /* IP multicast address of group */       struct in_addr imr_interface;   /* local IP address of interface */
};

struct ip_mreq mreq;

};

struct ip_mreq mreq;

setsockopt (socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));

2.接收消息

3.离开组

setsockopt (socket, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq));

7.广播组播注意事项:

1.设置缺省网关

route -n

route add default gw 192.168.5.1

2.防火墙

service iptables stop/start/restart/status

//=============================================================

1.网络数据库

#include <netdb.h>

gethostbyname --> 域名解析 /etc/hosts /etc/resolv.conf

getprotobyname --> /etc/protocols

2.设置网络选项

setsockopt(int sockfd,int level,int optname,const void *optval,socklen_t *optlen);

getsockopt(int sockfd,int level,int optname,void *optval,socklen_t *optlen);

level:

SOL_SOCKET 通用选项

SO_BROADCAST

SO_LINGER

SO_RCVBUF,SO_SNDBUF

SO_RCVLOWAT , SO_SNDLOWAT 低潮值

SO_REUSEADDR, SO_REUSEPORT

IPPROTO_IP ipv4选项

IP_TTL(time-to-live)

IP_ADDMEMBERSHIP

IP_DROPMEMBERSHIP

IPPROTO_IPV6 ipv6选项

IPPROTO_ICMPV6 icmpv6选项

IPPROTO_TCP tcp选项

3.IO模型

1.阻塞模型

2.非阻塞模型

fcntl(O_NONBLOCK);

if(read(...)<0)

{

if(errno==EGAIN)

{

//do other...

}

}

3.信号驱动IO sigio

4.异步IO

5.IO多路复用

Select:用于监视多个文件模型

网络编程注意事项:

1.优雅关闭问题

1.问题提出

发送者发送完毕,立即关闭连接,并且退出程序,此时接收者可能没有收完。(退出程序,即为原先发送者发送的数据存在缓冲区中,一旦程序退出,缓冲区则会被销毁,自然接受者收到的信息就不完全。)

2.解决

发送者:

1.发送完毕

2.shutdown(sockfd,SHUT_WR); //刷新缓冲  //shutdown可以关闭写 (TCP为全双工模型)

3.read(sockfd,&c,1);  //阻塞等待接受者发送一个消息给发送者,告诉发送者我已经发送完毕。此时有一种情况,若接受者没有发送信息给发送者,则read函数得到的为0,意味着接受者已关闭连接,则发送者也会因此而解除阻塞。

返回0

4.shutdown(sockfd,SHUT_RD);  //关闭读连接

接收者:

1.接收完毕

2.close(sockfd);

2.设置地址重用

socket之后,bind之前设置

int val = 1;

setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&val,sizeof(val))

2*msl  个时间断

3.数据传输

多字节

HBO-->NBO

NBO-->HBO

结构体

1字节补齐

多字节成员

...

4.tcp数据界限问题:读取写入固定字节,当然要采用readn writen保证数据的完整性。

readn

written

int readn(int fd,void *buf,size_t len)

{

int total = 0,n;

while(total<len)

{

again:

if((n = read(fd,buf+total,len-total))<0)

{

if(errno==EINTR)

goto again;

return -1;

}

else if(n==0)

break;

total += n;

}

return total;

}

5.MTU(max-transmition-unit),路径MTU

局域网:<1024

外网:<512

网络编程整理

时间: 2024-11-09 00:06:12

网络编程整理的相关文章

用java网络编程中的TCP方式上传文本文件及出现的小问题

自己今天刚学java网络编程中的TCP传输,要用TCP传输文件时,自己也是遇到了一些问题,抽空把它整理了一下,供自己以后参考使用. 首先在这个程序中,我用一个客户端,一个服务端,从客户端上传一个文本文件给服务端,服务端接收数据并显示“上传成功”给客户端. 客户端: 1 import java.io.BufferedReader; 2 import java.io.FileReader; 3 import java.io.IOException; 4 import java.io.InputStr

有哪些适合学生参与的 C++,网络编程方面的开源项目?

有哪些适合学生参与的 C++,网络编程方面的开源项目? Tinyhttpd是一个超轻量型Http Server,使用C语言开发,全部代码只有502行(包括注释),附带一个简单的Client,可以通过阅读这段代码理解一个 Http Server 的本质.下载链接链接:LippiOuYang/Tinyhttpd · GitHub nginx: download高性能web服务器 libevent/libevent · GitHubC语言写的事件驱动框架 ACE:C++面向对象网络编程工具包 Boos

网络编程——The C10K Problem(C10K = connection 10 kilo 问题)。k 表示 kilo,即 1000

The C10K problem翻译 (C10K = connection 10 kilo 问题).k 表示 kilo,即 1000 比如:kilometer(千米), kilogram(千克). 如今的web服务器需要同时处理一万个以上的客户端了,难道不是吗?毕竟如今的网络是个big place了. 现在的计算机也很强大了,你只需要花大概$1200就可以买一个1000MHz的处理器,2G的内存, 1000Mbit/sec的网卡的机器.让我们来看看--20000个客户,每个为50KHz,100K

java网络编程框架

虽然写过一些网络编程方面的东西,但还没有深入研究过这方面的内容,直接摘录一些文章,后续整理 原文地址:http://blog.csdn.net/lwuit/article/details/7306139 自从JDK1.4中有了NIO以后,这个方面越来越活跃,也为java赢得更多开发者的支持.做java网络编程需要掌握一些基本的知识和技能:套接字编程.阻塞/非阻塞通信.创建HTTP服务器与客户程序.数据报通信.对象的序列化与反序列化.Java反射机制.RMI框架.JDBC API.JavaMail

网络编程泛谈

本文目的在于整理一下网络编程过程中问题,旨在加深自己的理解,同时也供读者参考. 参考书:<UNIX网络编程> 从以下几个方面进行介绍: 网络编程的基础知识(TCP/IP协议) TCP客户端/服务器(echo服务)例子 高效的网络编程:阻塞/非阻塞,同步/异步,IO复用(select/poll/epoll学习,跨平台封装的库libev) 非阻塞+IO复用的echo服务 网络开发中的master/worker编程模型:Nginx/Uwsgi(这里再讨论下惊群问题) 多进程+非阻塞+IO复用的ech

VC++网络编程学习笔记

Visual C++网络编程是指用户使用MFC类库(微软基础类库)在VC编译器中,以实现网络应用.用户通过VC编程实现的网络软件可以在网络中不同的计算机之间互传文件,图像等信息.基础知识: 如果用户要进行VC网络编程,则必须首先了解计算机网络通信的基本框架和工作原理.在两台或多台计算机之间进行网络通信时,其通信的双方还必须遵循相同的通信原则好数据格式. 1.OSI七层网络模型OSI网络模型是一个开放式系统互联的参考模型. 发送信息的计算机 接收信息的计算机 7.应用层 7.应用层 表示计算机网络

Boost.Asio c++ 网络编程翻译(30)[完结]

PS:至此终于完成了Boost.Asio C++ network programming一书的翻译,这是我人生第一本完整翻译的书,从开始的磕磕绊绊,到最后小有心得,我收获很多.我将把这个系列的博客进行整理和校对,希望有兴趣的人可以帮我一起,来给大家提供更好更专业的阅读体验. 句柄追踪信息到文件 默认情况下,句柄的追踪信息被输出到标准错误流(相当于std::cerr).你想把输出重定向到其他地方的可能性是非常高的.对于控制台应用,输出和错误输出都被默认输出到相同的地方,也就是控制台.但是对于一个w

安卓 网络编程

这几天学校实训项目需要开始学习安卓编程,其中有一部分是涉及网络知识, 1 private class SendThread extends Thread 2 { 3 public SendThread(String s) 4 { 5 mURL = s; 6 } 7 public void run() 8 { 9 BasicHttpParams httpParams; 10 httpParams = new BasicHttpParams(); 11 HttpConnectionParams.se

Socket网络编程--聊天程序(5)

上一小节我们讲了使用select来避免使用多进程的资源浪费问题.上次只是实现了从多个客户端发送数据给服务器端,接下来就要实现从服务器端发送数据给各个服务器. 使用select多路转换处理聊天程序2 client.c 使用上一节用的那个,在那个基础上修改下面几句 66 //send-recv 一些返回指没有判断,具体可以看server.c 67 if((pid=fork())<0) 68 { 69 perror("fork error\n"); 70 } 71 else if(pi