Linux:网络编程

1、概述

 

 

2、字节序

 双字的意思:一个字节八位。两个字节就是三十二位

一个十六进制要用四个二进制表示

对内存来说,一个字节可以存放01

01 放一个字节,02放一个字节,03放一个字节,04 放一个字节

LE是小端的意思

低序字节就是04

高字节就是01

3、socket编程步骤

 服务器的开发步骤 :

1、套接字是为了后面的网络的操作提供一个基本对接的描述符的接口

(就像我们open 一个文件的fd 一样)

2、通过网络往外面走的通道已经建立好了(socket),但是这个通道是一个空白的通道,我们需要给这个通道添加一些信息(你的ip地址,端口号),把这个ip地址和端口号,绑定到套接字

 客户端:

只要给我一个通道,让我知道你的Ip 地址和端口号,调用connect()就可以链接

这个图的connect()的键号应该放在listen()后面有人监听,客户端发起connect(),服务端accept()

客户端建立连接。连接到服务端的时候,他们就建立数据的通道了,

你的 socket()通过bind()确定了Ip地址和端口号

四、linux 提供的API 简析

1、创建套接字

 

socket函数有点像open函数,它的目标是返回一个int 型 ,int 型也是一个文件描述符,只不过它是个网络描述符,跟我们做文件描述符,有稍微的区别,但是他们的意义是相似的

我们后面对网络的访问,都是基于文件描述符操作的

一般如果我们用  AF_IENT 就配合SOCK_STREAM

如果第一个用AF_IENT

第二个用SOCK_STREAM

第三个写0  ,就会自己分配 IPPROTO_TCP(你写这个宏也可以,写0也可以)

这就是第一步,创建套接字,创建套接字的时候,已经写明我是用哪种协议连接的

2、为套接字添加信息

你创建的套接字是个空的东西 ,

bind()里面的参数

第一个跟fd的意思一样,通过socket 的返回值的sockfd,就是我们的套接字描述符了

第二个是个结构体指针

第三个参数是第二个参数的长度

  一般用下面的

补充:地址转化API

第一个函数:

第一个参数是字符串,第二个参数就是我们的ip

第二个函数:

比如我们的服务器接入到客户的连接,我们想知道客户端的ip地址怎么办呢?

3、监听

第二个参数,是监听的总数

4、连接

 第二个参数是客户端的地址,

第三个参数是客户端地址的长度

补充:数据的收发

 

这个read 和write和我们文件的read write是一样的

你可以用read 和write也可以用其他的函数

 flags一般作为控制,是否有阻塞

其实除了这些还有呢

后面两套一般用于udp 的连接的

tcp一般用read(),write()    和recv()/send()

send() 发送 recv()接收

5、客户端的connect函数

 第一个参数 客户端socket()出来的文件描述符

第二个参数服务器的ip地址和端口号

第三个参数是整个地址的大小

五、socket服务端的代码实现

1、 创建套接字

返回值:

成功,返回一个新的套接字描述符,错误返回负1

 创建套接字的代码实现

2、 为套接字添加信息

 

那么sockadr_in 里面有哪些结构呢?

你可以在 usr/include底下搜索

 

 

记得空格然后再大括号

这种方式能搜到它定义的地方

在当前目录底下递归的来找

r:是递归的意思

n:是找出来显示行号

i:是不区分大小写

(找到一个头文件)

然后我们再来看看里面的184行

 端口号一般高于5000,小于3000是操作系统用的

作为用户一般用5000 到9000之间比较多

这个端口号会传到网络上去,我们必须调用某个函数,把他变成网络字节序

h是主机的意思

n是网络的意思

s代表短的意思

l代表长的意思

看看需要啥头文件

 有时候需要转化一下地址,要不然机器不认识

找一下地址转化的头文件

                 

 

记得bind()第二个参数强制转化

注意:第一个参数要一个字符串,第二个参数要一个指针

inet_aton的第二个参数取地址

 

3、监听和连接

当listen 没有收到数据的时候,accept会卡在那里

accept的返回值是一个新的建立的socket的通道。

我们通过套接字连接到这个客户端了,后续的连接选项的操做用accept 的返回值操作

之前的s_fd 可能还要接受别人的连接,一但连上以后,我们就先用c_fd操作

 

整体的思路:1、调用socket创建一个套接字

                2、配置那些东西的时候,首先是协议,

                        第二个是端口号,端口号要注意字节序        

                        第三个是ip地址,ip地址要注意人眼和机器认识的不一样

                        最终把你的ip地址和fd 绑定起来

                3、listen 去监听套接字,这里面监听了10个套接

                  4、accept没连接连上的时候,他会卡在这里

写个while(1)不让他退出,当有数据连上来的时候,打印一句话

如何验证写的是成功的还是不成功的呢?

可以在命令提示符下ping 一下,看一看地址能不能通

(虽然是台虚拟机,可是从软件层面上来说,还是两台不一样的电脑)

地址能通

 

 然后再用telnet

如果我们端口号写错了,写成7777

连接失败

记得先运行程序 

 这就是连接成功的

 这样是因为,咱们没有对数据的收发做操作

4、补充

上面的listen 一但配置完就会很快的结束的,程序会卡在accept那边

listen 只是告诉内核,我的这个服务器可以监听10个,10个里面有已经完成三次握手的和正在完成三次握手的,有两个队列合计是10个

accept会去判断你这个队列是否存在已经完成三次握手的客户端,已经完成三次握手的客户端,accept就会继续往下走,跟那个客户端进行连接,通过accept的返回值和客户端连接

我们来改一下上面的代码

首先我们想要获取客户端的信息,然后打印window的地址

memset做数据的清空

 运行的结果

 用telnet连接

 

 这就是连接上了

连接上以后我们做数据的交互

定义一个readBuf来收取数据

从c_fd里面读,读到readBuf里面,读128个字节

读到以后再给人回复一下(理论上计算一下回复的长度)

 

运行一下,连接成功后按个s试试

 发现是个cmd那面变成了乱码

 

会不会是cmd 的问题呢?

再用虚拟机试试,先连接

 

 在传输信息

 发现还是乱码

 原因是,我们发送的数据量太多了

改动一下:定义一个字符串

 

运行一下,先连接上

 然后打一句话试试
 

 六、socket客户端的代码实现

 第一个是fd,

第二个是指针

第三个是大小

客户端的代码实现

 运行结果

先运行server 会自己卡在那里 

 等着client运行的时候server 也会运行

 

 7、实现双方聊天

作为服务器我们不希望执行一次就退出

首先呢,如果我们的端口经常被占用,我们可以传参来配置端口

传进来的是字符串,我们要把ASCLL转化成整型数

客户端现在也是只写一次,多次的一会再改

服务端的代码

 

 客户端的代码

 

运行结果

并且我的服务端不会退出,支持多次连接

运行一次的结果

 运行好几次的结果

得出的结论

我的服务端不会退出,支持多次连接

我们可以试试cmd 环境下

连接后按一下s试试

这就实现了我们想要的效果:服务器接入多少个都不会退出

 

那么现在我想实现父进程和子进程聊天、

客户端:

子进程先改,connect以后我们不想让他退出,就做个while(1)循环,让父进程一直读

读的时候没数据会一直阻塞,写的话,我想有空就写,我可以不断创建子进程来写

服务端也改一下

if(fork() ==0)代表进入子进程

有新客户端进入的时候,调用子进程,子进程在这面等待读取对方的数据

等待之前先fork一下,目的是在这边去输入

记得加参数的判断

 

 运行的结果

先连接上

然后运行 

 运行一遍可以,但是运行多了就不会接收数据

思路:

有数据进来的时候,我创建一个子进程操作,子进程我希望他干两件事,同时执行两个while(1)

(想要执行两个while(1)要么用线程,要么用fork创建子进程,才能让两个while(1)同时跑)

这个能一直往套接字里面发送,同时还能读取套接字里面的信息

 

 

 

 

客户端的也修改一下

 

 

 

运行的结果:

可以正常的聊天了

 

 八、多方消息收发

我们实现自动回复,我们不实现获取用户的输入

(对我们来说,客户端1 客户端2 共用一个光标)

我们做一个mrck 按连接进来的顺序,标记一下,当我收到一个连接的时候,让mark++

现在服务端的功能,只能接收每一个客户端发上来的消息,

做个子进程每隔三秒给客户端发一句话,我就知道客户端的消息有没有丢失

对服务端来说呢?都能收到客户端的请求的

 

 

 

运行结果

这边每隔三秒就会收到welcome NO1

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值