linux 网络编程-基础篇01
#Socket简介
是一个编程接口
是一种特殊的文件描述符(everything in Unix is a file)
并不仅限于TCPIP协议
面向连接(Transmission Control Protocol - TCPIP)
无连接(User Datagram Protocol-UDP 和 Inter-Network Packet Exchange-IPX)
#Socket类型
流式套接字(SOCK_STREAM)
提供了一个面向连接,可靠的数据传输服务,数据无差错,无重复的发送且
按发送顺序接收。内设置流量控制,避免数据流淹没慢的接收方。数据被看作是
字节流,无长度限制
数据报套接字(SOCK_DGRAM)
提供无连接服务。数据包以独立数据包的形式被发送,不提供无差错保证,
数据可能丢失或重复,顺序发送,可能乱序接收
原始套接字(SOCK_RAW)
可以对较低层次协议如IP,ICMP直接访问
#IP地址
IP地址是Internet中主机的标识
Internet中的主机要与别的机器通信必须具有一个IP地址
IP地址为32位(IPV4)或者128位(IPV6)
每个数据包都必须携带目的IP地址和源IP地址,路由器依靠此信息为数据包
选择路由
表示形式:常用点分形式,如202.38.64.10,最后都会转换为一个32位的无符号
整数。
#IP地址的转换
inet_aton()
将strptr所指的字符串转换成32位的网络字节序二进制值
int inet_aton(const char *strptr, struct in_addr *addrptr);
inet_addr()
功能同上,返回转换后的地址
in_addr_t inet_addr(const char *strptr);
inet_ntoa()
将32位网络字节序二进制地址转换成点分十进制的字符串。
char *inet_ntoa(struct in_addr inaddr);
#端口号
为了区分一台主机接收到的数据包应该转交给哪个进程来进行处理,使用端口号
来区分
TCP端口号与UDP端口号独立(协议不同可以使用同一个端口)
三无组:协议,IP,端口
端口号一般由IANA(Internet Assigned Numbers Authority)管理
众所周知端口:1~1023(1~255之间为众所周知端口,256~1023端口通常由
UNIX系统占用
已登记端口:1024~49151
动态或私有端口:49152~65535
#字节序
不同类型CPU的主机中,内存存储多字节整数序列有两种方法,称为主机字节序(HBO):
小端序(little-endian)-低字节存储在低地址
将低字节存储在起始地址,称为"Little-Endian"字节序,Intel,AMD等
采用的是这种方式
大端序(big-endian)-高序字节存储在低地址
将高字节存储在起始地址,称为"Big-Endian"字节序,由ARM,Motorola
等所采用
网络中传输的数据必须按网络字节序,即大端字节序
在大部分PC机上,当应用进程将整数送入socket前,需要转化成网络字节序;当
应用进程从socket取出整数后,要转化成小端字节序
#字节序转换函数
把给定系统所采用的字节序称为主机字节序,为了避免不同类别主机之间在数据
交换时由于对于字节序的不用而导致的差错,引入了网络字节序
主机字节序到网络字节序:
u_long htonl(u_long hostlong);
u_short htons(u_short short);
网络字节序到主机字节序
u_long ntohl(u_long hostlong);
u_short ntohs(u_short short);
#网络编程相关API
int Socket(int domain, int type, int protocol);
int bind(int Sockfd, struct sockaddr *my_addr, int addrlen);
int listen(int sockfd, in backlog);
int accept(int sockfd, struct sockaddr *addr, Socklen_t *addrlen);
int connect(int sockfd, const struct sockaddr *addr, Socklen_t addrlen);
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, Socklen_t addrlen);
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, Socklen_t *addrlen);
int shutdown(int sockfd, int how);
#command:
netstat -anpt
#地址结构的一般用法
1.定义一个struct sockaddr_in类型的变量并清空
struct sockaddr_in myaddr;
memset(&myaddr, 0, sizeof(myaddr));
2.填充地址信息
myaddr.sin_family = PF_INET;
myaddr.sin_port = htons(8888);
myaddr.sin_addr.s_addr = inet_addr("192.168.1.100");
3.将该变量强制转换为struct sockaddr类型在函数中使用
bind(listenfd,(struct sockaddr *)&myaddr, sizeof(myaddr));
#地址转换函数
unsigned long inet_addr(const char *address);
int inet_aton(const char *cp, struct in_addr *inp);
char *inet_ntoa(struct in_addr in);
socket流程图:

附:代码
client.c
//int socket(int domain, int type, int protocol);
//int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
//int listen(int sockfd, int backlog);
//int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
//uint16_t htons(uint16_t hostshort);
//int atoi(const char *nptr);
//in_addr_t inet_addr(const char *cp);
//void bzero(void *s, size_t n);
//int listen(int sockfd, int backlog);
//int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
//int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); #include <stdio.h>
#include <sys/types.h>//socket():bind();listen():accept();listen();accept();connect();
#include <sys/socket.h>//socket():bind();listen():accept();inet_addr();listen():accept();connect();
#include <arpa/inet.h>//htons();inet_addr():
#include <netinet/in.h>//inet_addr():
#include <strings.h>//bzero();
#include <stdlib.h>//atoi();exit();
#include <unistd.h>//close():
#include <string.h> #define N 64 int main(int argc, char *argv[])
{
if(argc < )
{
printf("Using: %s ip port\n",argv[]);
exit(-);
}
int sockfd;
struct sockaddr_in myaddr,peeraddr;
char buf[N] = {};
size_t n;
socklen_t mylen,peerlen;
mylen = sizeof(myaddr);
peerlen = sizeof(peeraddr);
/* creat socket */
if(- == (sockfd = socket(AF_INET,SOCK_DGRAM,)))
{
perror("socket");
exit(-);
}
/* bind initialization */
bzero(&myaddr,sizeof(myaddr));
myaddr.sin_family = AF_INET;
myaddr.sin_port = htons(atoi(argv[])+);
myaddr.sin_addr.s_addr = inet_addr(argv[]);
/* bind */
if(- == bind(sockfd, (struct sockaddr *)&myaddr, mylen))
{
perror("bind");
exit(-);
}
/* connect */
bzero(&peeraddr, sizeof(peeraddr));
peeraddr.sin_family = AF_INET;
peeraddr.sin_port = htons(atoi(argv[]));
peeraddr.sin_addr.s_addr = inet_addr(argv[]);
//connect(sockfd,(struct sockaddr *)&peeraddr, peerlen);
while(){
fgets(buf, N, stdin);
printf("buf:%s",buf);
if(- == (n = sendto(sockfd, buf, strlen(buf), , (struct sockaddr *)&peeraddr, peerlen)))
{
perror("sendto");
exit(-);
}
if(strncmp(buf, "quit", ) == )
break;
printf("n = %d\n",n);
}
close(sockfd);
exit();
}
server.c
#include <stdio.h>
#include <sys/types.h>//socket():bind();listen():accept();listen();accept();connect();
#include <sys/socket.h>//socket():bind();listen():accept();inet_addr();listen():accept();connect();
#include <arpa/inet.h>//htons();inet_addr():
#include <netinet/in.h>//inet_addr():
#include <strings.h>//bzero();
#include <stdlib.h>//atoi();exit();
#include <unistd.h>//close():
#include <string.h> #define N 64 typedef struct sockaddr SA; int main(int argc, char *argv[])
{
if(argc < )
{
printf("Using: %s ip port\n",argv[]);
exit(-);
} int listenfd, connfd;
struct sockaddr_in myaddr, peeraddr;
char buf[N] = {};
size_t n;
socklen_t mylen, peerlen;
mylen = sizeof(myaddr);
peerlen = sizeof(peeraddr);
/* create socket */
if ((listenfd = (socket(PF_INET, SOCK_DGRAM, ))) < )
{
perror("socket");
exit(-);
}
/* bind initialization */
bzero(&myaddr, mylen);
myaddr.sin_family = PF_INET;
myaddr.sin_port = htons(atoi(argv[]));
inet_aton(argv[], &myaddr.sin_addr); if(bind(listenfd,(SA *)&myaddr, sizeof(myaddr)) < )
{
perror("bind");
exit(-);
}
/* listen */
listen(listenfd, );
/* accept */
if(- == (connfd = accept(listenfd, (SA *)&peeraddr, &peerlen)))
{
perror("accept");
exit(-);
}
printf("connect from %s: %d\n",inet_ntoa(peeraddr.sin_addr), ntohs(peeraddr.sin_port));
/* recv-send */
while(){
n = recv(connfd, buf, N, );
buf[n] = ;
printf("n = %d---%s\n",n,buf);
if( == strncmp(buf,"quit",))
break;
send(connfd, buf, strlen(buf), );
}
close(connfd);
close(listenfd);
exit();
}
原文链接:http://www.cnblogs.com/lr-ting/archive/2012/08/24/2652482.html
----
linux 网络编程-基础篇01的更多相关文章
- 服务器编程入门(4)Linux网络编程基础API
问题聚焦: 这节介绍的不仅是网络编程的几个API 更重要的是,探讨了Linux网络编程基础API与内核中TCP/IP协议族之间的关系. 这节主要介绍三个方面的内容:套接字( ...
- Linux 高性能服务器编程——Linux网络编程基础API
问题聚焦: 这节介绍的不仅是网络编程的几个API 更重要的是,探讨了Linux网络编程基础API与内核中TCP/IP协议族之间的关系. 这节主要介绍三个方面的内容:套接字(so ...
- 第5章 Linux网络编程基础
第5章 Linux网络编程基础 5.1 socket地址与API 一.理解字节序 主机字节序一般为小端字节序.网络字节序一般为大端字节序.当格式化的数据在两台使用了不同字节序的主机之间直接传递时,接收 ...
- Linux网络编程基础API
第5章 Linux网络编程基础API 探讨Linux网络编程基础API与内核中TCP/IP协议族之间的关系,并未后续章节提供编程基础.从3个方面讨论Linux网络API. socket地址API.so ...
- linux高性能服务器编程 (五) --Linux网络编程基础api
第五章 Linux网络编程基础api 1.主机字节序和网络字节序 字节序是指整数在内存中保存的顺序.字节序分为大端字节序.小端字节序. 大端字节序:一个整数的高位字节数据存放在内存的低地址处.低位字节 ...
- linux 网络编程 基础
网络编程基础 套接字编程需要指定套接字地址作为参数,不同的协议族有不同的地址结构,比如以太网其结构为sockaddr_in. 通用套接字: struct sockaddr { sa_family_t ...
- linux网络编程基础--(转自网络)
转自 http://www.cnblogs.com/MyLove-Summer/p/5215287.html Linux下的网络编程指的是socket套接字编程,入门比较简单. 1. socket套接 ...
- Linux网络编程基础
1. Linux网络模型 ① OSI七层模型和Linux四层模型 ② 各种协议之间的关系及在Linux模型中的位置 ③ 协议封装:各种协议处于一种层层封装的关系 (1)Ethernet (2)IP * ...
- Linux 网络编程基础(1)--网络相关的数据结构及转化函数
在Linux下进行网络编程,使用的语言一般为C.就个人感受而言,在Linux下进行网络程序的编写,重要的不是代码能力要多强,而是对Linux的网络编程思想的理解和对Linux网络数据结构的掌握.如果想 ...
随机推荐
- ajax aspx调用webservice,返回json
1,创建一个asp.net网站 2.创建一个student类 using System; using System.Collections.Generic; using System.Linq; us ...
- ORACLE索引介绍和使用
1.什么是索引 索引是建立在表的一列或多个列上的辅助对象,目的是加快访问表中的数据: Oracle存储索引的数据结构是B*树,位图索引也是如此,只不过是叶子节点不同B*数索引: 索引由根节点.分支节点 ...
- 17Aspectij
17Aspectij-2018/07/31 1.Aspectj基于xml 前置通知 method : 通知,及方法名 pointcut :切入点表达式,此表达式只能当前通知使用. pointcut-r ...
- 洛谷——P3003 [USACO10DEC]苹果交货Apple Delivery
P3003 [USACO10DEC]苹果交货Apple Delivery 这题没什么可说的,跑两遍单源最短路就好了 $Spfa$过不了,要使用堆优化的$dijkstra$ 细节:1.必须使用优先队列+ ...
- 洛谷——P1273 有线电视网
P1273 有线电视网 题目大意: 题目描述 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树 ...
- zabbix+docker
由于公司线上服务器数量太少,又要用于生产,领导让上zabbix,但熟知zabbix搭建需要LAMP或者LNMP,如果和生产服务器混搭的话,不方便管理,也怕出问题,所以就先使用docker方式搭建管理. ...
- MySql-了解存储引擎
怎么应对不同版本 在不同的 mysql 版本中,很多特性和语法有可能是不一样的,我们怎么样才能知道当前版本的语法是什么样呢?最好的办法是学会使用 mysql 的帮助. A.按照层次看帮助 例如:mys ...
- UVA - 10825 Anagram and Multiplication
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34594 有一个m位n进制的数,它的特性是这个数依次乘以2,3... ...
- Leetcode 22.生成括号对数
生成括号对数 给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合. 例如,给出 n =3,生成结果为: [ "((()))", "( ...
- android在listview中放入从sdcard读取的bitmap
重写viewbinder public class viewbinder_bookmark implements SimpleAdapter.ViewBinder{ @Override public ...