54.Linux 网络编程
socket函数:
#include <sys/socket.h>
int socket(int domain,int type,int protocol); 创建一个套接字
domain(领域) :AF_INET、AF_INET6、AF_UNIX
type: SOCK_STREAM、SOCK_DGRAM
protocol:0
返回值:成功:新套接字所对应的文件描述符
失败:-1 errno
bind()函数:
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
给socket绑定一个IP和port
sockfd:socket函数返回值
addr:(struct sockaddr *)&addr;
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(8888); //端口号
addr.sin_addr.s_addr = htol(INADDR_ANY); //取出系统中有效的任意IP地址。二进制类型。
addrlen:sizeof(addr);
返回值:成功:0
失败:-1 errno
listen函数
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int listen(int sockfd, int backlog);
设置同时与服务器建立连接的上限数。(同时进行3次握手的客户端数量)
sockfd:socket函数返回值
backlog:上限数值,最大值128
返回值:
成功:0
失败:-1 errno
accept函数
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); 阻塞等待客户端建立连接
sockfd:socket函数返回值
addr:传出参数。成功与服务器建立连接的那个客户端的地址结构(IP+port)。
socklen_t client_addr_len = sizeof(addr);
addrlen:传入传出 &client_addr_len
入:addr的大小。出:客户端addr实际大小。
返回值:能与服务器进行数据通信的socket对应的文件描述符
成功:返回一个与客户端成功连接的socket文件描述符
失败: -1 errno
connect函数
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
使用现有的socket与服务器建立连接
sockfd:socket函数返回值
struct sockaddr_in srv_addr; //服务器地址结构
srv_addr.sin_family=AF_INET;
srv_addr.sin_port=666; //跟服务器端口号一致
inet_pton(AF_INET,“服务器的IP号”,&srv_addr.sin_addr.s_addr);
addr:传入参数。服务器的地址结构
addrlen:服务器的地址结构的长度
返回值:成功:0
失败·:-1
TCP通信流程分析:
server:
1.socket() 创建socket
2.bind() 绑定服务器地址结构
3.listen() 设置监听上限
4.accept() 阻塞,监听客户端连接
5.read() 读socket获取客户端数据
6.小---大写 toupper():小写转大写
7.write()
8.close()
client:
1.socket() 创建socket
2.connect() 与服务器建立连接
3.write() 写数据到socket
4.read() 读转换后的数据
5.显示读取结果
6.close()
inet_ntop函数
inet_pton()和inet_ntop()函数允许在IPv4和IPv6地址的二进制形式和点分十进制表示法或十六进制字符串表示法之间进行转换。
#include <arpa/inet.h>
const char *inet_ntop(int domain, const void *addrptr,char *dst_str, socklen_t size);
这些函数名中的p表示“展现(presentation)”,n表示“网络(network)”。展现形式是人类可读的字符串,如:
198.152.189.116(IPv4点分十进制地址);
::1(IPv6冒号分隔的十六进制地址);
::FFFF:198.152.189.116(IPv4映射的IPv6地址)。
inet_ntop()函数执行逆向转换。同样,
①domain应该被指定为AF_INET或AF_INET6,
②addrptr应该指向一个待转换的in_addr或in_addr6结构
③得到的以null结尾的字符串会被放置在dst_str指向的缓冲区中。
④len参数必须被指定为这个缓冲区的大小。
服务器:
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/un.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <time.h>
#include <ctype.h>
#define SERV_PORT 666int main(int argc,char *argv[])
{int sockfd,client_fd;struct sockaddr_in serv_addr,client_addr;socklen_t client_addr_len;int ret;char buf[BUFSIZ],client_IP[1024];serv_addr.sin_family=AF_INET;serv_addr.sin_port=htons(SERV_PORT);serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);sockfd=socket(AF_INET,SOCK_STREAM,0);if(sockfd==-1){perror("socket");exit(1);}bind(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr));listen(sockfd,128);
//int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);client_addr_len=sizeof(client_addr);client_fd=accept(sockfd,(struct sockaddr *)&client_addr,&client_addr_len);if(client_fd==-1){perror("accept");exit(1);}
//const char *inet_ntop(int af, const void *src,char *dst, socklen_t size);printf("client ip:%s port:%d\n",inet_ntop(AF_INET,&client_addr.sin_addr.s_addr,client_IP,sizeof(client_IP)),htons(client_addr.sin_port));while(1){ret=read(client_fd,buf,sizeof(buf));write(STDOUT_FILENO,buf,ret);for(int i=0;i<ret;i++)buf[i]=toupper(buf[i]);write(client_fd,buf,ret);}close(sockfd);close(client_fd);return 0;
}
客户端
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/un.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <time.h>
#include <ctype.h>
#include <arpa/inet.h>#define SERV_PORT 666int main(int argc,char *argv[])
{int client_fd;int counter=10;char buf[BUFSIZ];struct sockaddr_in serv_addr;serv_addr.sin_family=AF_INET;serv_addr.sin_port=htons(SERV_PORT);
//int inet_pton(int af, const char *src, void *dst);inet_pton(AF_INET,"127.0.0.1",&serv_addr.sin_addr.s_addr); client_fd=socket(AF_INET,SOCK_STREAM,0);if(client_fd==-1){perror("socket");exit(1);}
//int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);int ret=connect(client_fd,(struct sockaddr *)&serv_addr,sizeof(serv_addr));if(ret!=0){ perror("connect"); exit(1);}
//ssize_t write(int fd, const void *buf, size_t count);
//ssize_t read(int fd, void *buf, size_t count);while(counter--){write(client_fd,"hello",5); ret=read(client_fd,buf,sizeof(buf));write(STDOUT_FILENO,buf,ret);}close(client_fd);return 0;
}
54.Linux 网络编程相关推荐
- Linux网络编程服务器模型选择之并发服务器(上)
转载:http://www.cnblogs.com/lizhenghn/p/3617666.html 与循环服务器的串行处理不同,并发服务器对服务请求并发处理.循环服务器只能够一个一个的处理客户端的请 ...
- 很全的linux网络编程技巧
注:作者王晓,本人认为总结得很好,故记之,绝无侵权之意. 本文转自:https://www.cnblogs.com/jfyl1573/p/6476607.html 看到好文章想留做自己学习,如有侵权, ...
- Linux网络编程--进程间通信(一)
进程间通信简介(摘自<Linux网络编程>p85) AT&T 在 UNIX System V 中引入了几种新的进程通讯方式,即消息队列( MessageQueues),信号量( s ...
- Linux io模型及函数调用,Linux 网络编程的5种IO模型:信号驱动IO模型
Linux 网络编程的5种IO模型:信号驱动IO模型 背景 这一讲我们来看 信号驱动IO 模型. 介绍 情景引入: 在信号驱动IO模型中,当用户线程发起一个IO请求操作,会给对应的socket注册一个 ...
- Linux网络编程实例分析
最近由于工作原因需要温习一下Linux网络编程的部分基础知识,因此对之前写的Socket网络通信的代码进行了进一步优化和拓展,在不关闭一次Socket连接的基础上,对服务端加入循环读写的功能,同时加入 ...
- Linux网络编程必看书籍推荐
首先要说讲述计算机网络和TCP/IP的书很多. 先要学习网络知识才谈得上编程 讲述计算机网络的最经典的当属Andrew S.Tanenbaum的<计算机网络>第五版,这本书难易适中. &l ...
- [Linux网络编程学习笔记]套接字地址结构
好久没有看那Linux网络编程这本书了,今天看到了重点部分-TCP套接字.下面先来看看套接字的地址结构 Linux系统的套接字可以支持多种协议,每种不同的协议都是用不同的地址结构.在头文件<li ...
- linux网络编程二:基础socket, bind, listen, accept, connect
linux网络编程二:基础socket, bind, listen, accept, connect 1. 创建socket #include <sys/types.h> #inc ...
- linux网络编程常用函数详解与实例(socket--bind--listen--accept)
常用的网络命令: netstat 命令netstat是用来显示网络的连接,路由表和接口统计等网络的信息.netstat有许多的选项我们常用的选项是 -an 用来显示详细的网络状态.至于其它的选项我们可 ...
最新文章
- CUDA support is required (OpenCV CMake parameter ‘WITH_CUDA‘ must be true).
- 差异与阵列和阵列结构和链表的区别
- 泰语7个元音变形_大概是最全的音标总结--元音部分
- enum.values_占用内存的Enum.values()方法
- C#反序列化 “在分析完成之前就遇到流结尾”
- 邻近算法(KNN算法)
- BOOST1.54简化编译
- 阶段3 1.Mybatis_05.使用Mybatis完成CRUD_7 Mybatis中参数的深入-使用实体类的包装对象作为查询条件...
- MFC用户界面设计 一
- NetFramework3.5 win10 64位 32位 安装资源——免费下载
- 高并发,我把握不住啊!
- pycharm复制代码出现空格
- 什么软件测试苹果手机循环电池,教你如何检测苹果手机电池的损耗
- 如何将多个excel表格合并成一个_怎么将多个pdf文件合并成一个?
- Arduino UNO AT24C32进行字符串数据读写【优化篇】
- 数据安全评估体系建设
- Slurm如何应对超大作业的NSS压力?
- 用更简单的方式画森林图
- 因子分析SPSS数学建模
- 解决百度网盘限速的问题