TCP/IP协议:
1.网络层:
Internet 协议(IP)
该协议被设计成互联分组交换通信网,以形成一个网际通信环境。它负责在源主机和目的地主机之间传输来自其较高层软件的称为数据报文的数据块,它在源和目的地之间提供非连接型传递服务
网际控制报文协议(ICMP)
它实际上不是IP层部分,但直接同IP层一起工作,报告网络上的某些出错情况。允许网际路由器传输差错信息或测试报文。
地址解析协议(ARP)
ARP 实际上不是网络层部分,它处于IP和数据链路层之间,它是在32位IP地址和48位物理地址之间执行翻译的协议
2.传输层协议:
传输控制协议(TCP):
该协议对建立网络上用户进程之间的对话负责,它确保进程之间的可靠通信,所提供的功能如下:
1.监听输入对话建立请求
2.请求另一网络站点对话
3.可靠的发送和接收数据
4.适度的关闭对话
用户数据报文协议(UDP):
UDP 提供不可靠的非连接型传输层服务,它允许在源和目的地之间传送数据,而不必在传送数据之前建立对话。它主要用于那些非连接型的应用程序,如:视频点播
TCP与UDP:
TCP是重要的传输层协议,目的是允许数据同网络上的其他节点进行可靠的交换。
它能提供端口编号的译码,以识别主机的应用程序,而且完成数据的可靠传输TCP 协议具有严格的内装差错检验算法确保数据的完整性TCP 是面向字节的顺序协议,这意味着包内的每个字节被分配一个顺序编号,并分配给每包一个顺序编号。
UDP也是传输层协议,它是无连接的,不可靠的传输服务.当接收数据时它不向发送方提供确认信息,它不提供输入包的顺序,如果出现丢失包或重份包的情况,也不会向发送方发出差错报文.由于它执行功能时具有较低的开销,因而执行速度比TCP快。
Socket:
Linux中的网络编程通过Socket(套接字)接口实现,Socket是一种文件描述符
套接字Socket
struct sockaddr_in
{
short int sin_family; /* Internet地址族 */
unsigned short int sin_port; /* 端口号 */
struct in_addr sin_addr; /* IP地址 */
unsigned char sin_zero[8]; /* 填0 */
};
进行Socket编程的常用函数有:
socket
创建一个socket
bind
用于绑定IP地址和端口号到socket
connect
该函数用于绑定之后的client端与服务器建立连接
listen
设置能处理的最大连接要求,Listen()并未开始接收连线,只是设置socket为listen模式。
accept
用来接受socket连接。
send
发送数据
recv
接收数据
例:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#define PORT 8888
int main()
{
int sockfd, ret, fd;
char buf[100] = {0};
struct sockaddr_in server_addr; //用于存放服务器本身的信息,包括自己的port和ip
struct sockaddr_in client_addr; //接受客户端连接的时候, 用于存放客户端信息
printf("Start Server!\n");
sockfd = socket(PF_INET, SOCK_STREAM, 0); //创建socket,处理客户端的连接,不用于发送信息
if (-1 == sockfd)
{
perror("socket");
exit(1);
}
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = PF_INET; //地址族
server_addr.sin_port = PORT; //指定socket的端口号
server_addr.sin_addr.s_addr = inet_addr("192.168.1.111"); //本机ip
ret = bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)); //上述信息绑定到socket
if (-1 == ret)
{
perror("bind");
exit(1);
}
printf("Listening...\n");
ret = listen(sockfd, 5); //监听,是否有客户端发起连接
if(-1 == ret)
{
perror("listen");
exit(1);
}
int length = sizeof(client_addr);
fd = accept(sockfd, (struct sockaddr *)&client_addr, &length);//接受客户端的连接,返回值用于发送信息
if (-1 == fd)
{
perror("accept");
exit(1);
}
printf("Accept %d , Port %d\n", fd, client_addr.sin_port);
while (1)
{
ret = recv(fd, buf, sizeof(buf), 0); //接收消息,从fd里面接收
if (-1 == ret)
{
perror("recv");
exit(1);
}
if (!strcmp(buf, "bye"))
{
break;
}
printf("Recv From Client : %s\n", buf);
memset(buf, 0, sizeof(buf));
}
close(fd);
close(sockfd);
return 0;
}
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 8888
int main()
{
int sockfd, ret;
struct sockaddr_in server_addr; //向server_addr发起连接
char buf[100] = {0};
sockfd = socket(PF_INET, SOCK_STREAM, 0); //创建socket,既用于连接,又用于发送消息
if (-1 == sockfd)
{
perror("socket");
exit(1);
}
memset(&server_addr, 0, sizeof(server_addr)); //都是服务器的信息
server_addr.sin_family = PF_INET;
server_addr.sin_port = PORT;
server_addr.sin_addr.s_addr = inet_addr("192.168.1.111");
printf("Start Connecting...\n");
ret = connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));//发起连接
if (-1 == ret)
{
perror("connect");
exit(1);
}
while (1)
{
scanf("%s", buf);
ret = send(sockfd, buf, strlen(buf), 0); //发送消息
if (-1 == ret)
{
perror("send");
exit(1);
}
if (!strcmp(buf, "bye"))
{
break;
}
memset(buf, 0, sizeof(buf));
}
close(sockfd);
return 0;
}