最近学习了下UNIX下的网络编程。为了以后查询方便,总结在这里。

首先套接字的地址定义:

   IPv4地址和IPv6地址定义见<netinet/in.h>头文件定义。为了能够顺利转换不同的套接字内容,可以查看<sys/socket.h>中定义的通用套接字struct sockaddr;在使用过成中我们可以将struct sockaddr_in 和 sockaddr_in6直接强制转换成struct sockaddr.

连接过程中我们需要人工指定对应网络地址。而不同的主机实现中存在不同的数据格式(big-endian OR little-endian),我们需要通过如下转换函数来保证数据转换过程中的正确性。

函数列表如下:   

#include <netinet/in.h>
//from host byte order to network byte order
uint16_t htons(uint16_t  host16bitvalue)//servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
uint32_t htonl(uint32_t  host32bitvalue)//from network byte order to host byte order
uint16_t ntohs(uint16_t  host16bitvalue)
uint16_t ntohl(uint16_t  host16bitvalue)

地址转换函数使用:

#include <arpa/inet.h>int inet_pton(int family, const char* strptr, void *addrptr);  //成功返回1,格式错误返回0,出错返回-1//示例::Inet_pton(AF_INET, argv[1], &serveraddr.sin_addr);const char* inet_ntop(int family, const void*addrptr, char *strptr, size_t len); //len参数指出缓存区的大小,避免出现溢出

基本TCP套接字编程示例程序如下(这里我们read,write等系统IO操作来实现网络回射服务):

其中涉及到的网络编程函数包括:socket(),bind(),bzero(),inet_pton(), listen(),connect(),accept()

服务过程中socket()指定所要进行操作的网络服务是什么, socket(指定协议族, 操作类型, 采用协议)

协议族包括:AF_INET:Pv4;  AF_INET6:IPv6;  AF_LOCAL:UNIX域协议;  AF_ROUTE:路由套接字;  AF_KEY:密钥套接字

操作类型:SOCK_STREAM:字节流;  SOCK_DGRAM:数据报;  SOCK_SEQPACKET:有序分组;  SOCK_RAW:原始套接字

采用协议:IPPROTO_TCP...._UDP...._SCTP

需要注意的问题:

  Fork子进程后,connfd和listenfd的引用次数变成2,所以需要在子进程和父进程中同时关闭才能保证完全关闭。

  多个子进程并发后,会在服务器上产生大量的僵死进程,从而使得大量的服务器资源浪费。为此我们需要捕获僵死进程的信号SIGCHLD,并做相应的处理。因为UNIX中信号不排队的设计,采用wait处理完第一个僵死进程的信号后其余的进程信号丢失。从而清理不彻底。为此,这里采用waitpid函数进行处理。

首先,服务器程序:

#include "unp.h"
#include <stdio.h>
#include <stdlib.h>void str_echo(int sockfd);
Sigfunc* signal1(int signo, Sigfunc* func);
void sig_child(int signo);
int main(int argc, char** argv){int listenfd, connfd;char buff[MAXLINE];pid_t childpid;socklen_t clilen;struct sockaddr_in cliaddr, servaddr;//<sys/socket.h>//int socket(int family, int type, int protocal);listenfd = Socket(AF_INET, SOCK_STREAM, 0);bzero(&servaddr, sizeof(struct sockaddr_in));servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = htonl(INADDR_ANY);servaddr.sin_port = htons(SERV_PORT);Bind(listenfd, (SA*) &servaddr, sizeof(servaddr));Listen(listenfd, LISTENQ);//working with the
    signal1(SIGCHLD, sig_child);while(1){clilen = sizeof(cliaddr);connfd = Accept(listenfd, (SA*)&cliaddr, &clilen);if ((childpid = Fork()) == 0){Close(listenfd);str_echo(connfd);exit(0);}Close(connfd);}return 0;
}void str_echo(int sockfd){ssize_t n;char buf[MAXLINE];
again:while((n = read(sockfd, buf, MAXLINE) ) > 0)Write(sockfd, buf, n);if (n < 0 && errno == EINTR)goto again;else if (n < 0)err_sys("str_echo: read error");}Sigfunc* signal1(int signo, Sigfunc* func){struct sigaction act, oact;act.sa_handler = func;sigemptyset(&act.sa_mask);act.sa_flags = 0;if ( signo == SIGALRM){
#ifdef SA_INTERRUPT//设定中断,使该信号处理过程中能够中断:act.sa_flags |= SA_INTERRUPT;
#endif}else{
#ifdef    SA_RESTART//信号处理,设置SA_RESTART标志,使得内核对失败的//系统调用自动重启。act.sa_flags |= SA_RESTART;
#endif}if (sigaction(signo, &act, &oact) < 0){return SIG_ERR;}return (oact.sa_handler);
}void sig_child(int signo){pid_t pid;int stat;/***********************************************
#inlcude <sys/wait.h>这里使用wait函数只能处理第一个返回的僵死进程,因为其UNIX系统信号实现中信号是不进行排队的。所以我们采用waitpid并且设定最后的选项为WNOHANG.表示内核在没有进程时不仅行阻塞。***********************************************///  --- pid = wait(&stat);while(( pid = waitpid(-1, &stat, WNOHANG)) > 0)printf("child %d terminated.\n", pid);return;
}

客户端程序:

#include "unp.h"
#include <stdio.h>
#include <stdlib.h>int str_cli1(FILE *fp, int sockfd);int main(int argc, char** argv){int sockfd[5];struct sockaddr_in serveraddr;int i;if (argc < 2)err_quit("Use: clisocket <IPaddress>");for (i = 0; i <5; ++i){sockfd[i] = Socket(AF_INET, SOCK_STREAM,0);bzero(&serveraddr, sizeof(struct sockaddr_in));serveraddr.sin_family = AF_INET;serveraddr.sin_port = htons(SERV_PORT);Inet_pton(AF_INET, argv[1], &serveraddr.sin_addr);Connect(sockfd[i], (SA*)&serveraddr, sizeof(serveraddr));}str_cli(stdin, sockfd[0]);exit(0);
}int str_cli1(FILE *fp, int sockfd){char sendline[MAXLINE], recvline[MAXLINE];while(Fgets(sendline, MAXLINE, fp) != NULL){Writen(sockfd, sendline, strlen(sendline));if (Readline(sockfd, recvline, MAXLINE) == 0)err_quit("str_cli: server terminated prematurely");Fputs(recvline, stdout);}
}

转载于:https://www.cnblogs.com/BeDPS/p/3693088.html

基本套接字总结(@function)相关推荐

  1. day7 面向对象进阶、socket套接字

    文章目录 1. 静态方法.类方法 1.1 静态方法 1.2 类方法 2. 属性方法 3. 类的一些成员方法 4. 反射 5. 异常处理 6. socket 套接字 1. 静态方法.类方法 1.1 静态 ...

  2. python 图形化socket编程_Python黑帽编程2.8 套接字编程

    Python黑帽编程2.8 套接字编程 套接字编程在本系列教程中地位并不是很突出,但是我们观察网络应用,绝大多数都是基于Socket来做的,哪怕是绝大多数的木马程序也是如此.官方关于socket编程的 ...

  3. Python网络编程2:创建套接字和套接字对象的内建方法

    1.使用socket模块中socket()函数创建套接字: socket()函数返回一个socket对象,该对象的方法实现了各种socket系统调用. 语法: import socket socket ...

  4. 第2章 基本的TCP套接字

    2.1 IPv4 TCP客户端     4个步骤: (1) socket()创建TCP套接字(window下要用初始化套接字环境) (2) connect()建立到达服务起的连接 (3) send() ...

  5. tcp/ip 协议栈Linux内核源码分析14 udp套接字接收流程一

    内核版本:3.4.39 前面两篇文章分析了UDP套接字从应用层发送数据到内核层的处理流程,这里继续分析相反的流程,看看数据是怎么从内核送到应用层的. 与发送类似,内核也提供了多个接收数据的系统调用接口 ...

  6. tcp/ip 协议栈Linux内核源码分析12 udp套接字发送流程一

    内核版本:3.4.39 因为过往的开发工作中既包括内核网络层模块的开发,又包括应用层程序的开发,所以对于网络数据的通信有那么一些了解.但是对于网络通信过程中,内核和应用层之间接口是如何运作的不是很清楚 ...

  7. c语言socket鉴权,建立套接字后进行socket.io身份验证

    小编典典 这实际上并不难,但是您正以错误的方式进行处理.几件事: 您不能使用socket.io 设置 cookie:但是,您可以随时获取任何已连接客户端的cookie值.为了设置cookie,您将必须 ...

  8. C语言socket connect()函数(初始化套接字上的连接)(未完)(如何测试socket是否已经断开,如何判断socket是否断开)

    参考文章:C网络编程socket之connect函数 需研究下这个函数超时多久才返回... 文章目录 项目中注释解释 man 2 文档解释 关于上面man 2 手册中所提到的connect()案例,在 ...

  9. muduo网络库学习(二)对套接字和监听事件的封装Channel

    muduo对描述符fd,需要监听的事件events,当fd被激活调用的可读/可写/关闭/错误回调函数进行了封装,实现在Channel类中,Poller监听的其实就是一个个Channel对象,Chann ...

最新文章

  1. lnmp之mysql原码编译
  2. php this 代表什么,php中$this-)是什么意思?
  3. getElementByName????????,????????,
  4. shell编程面试必会30题
  5. oracle tranc,oracle函数trunc的使用
  6. vscode请更新includepath_VS Code Java 九月更新!Coding Pack for Java 带来一键安装新体验!...
  7. 拨盘Demo大赛,获奖公布-20170710
  8. edittext实现自动查询,刷新listview
  9. 周鸿祎吐槽乘坐达美航空奇葩经历:飞机飞到半路 机组说要下班
  10. 计算机一级在线解析,2016年计算机一级试题及答案解析
  11. ZooKeeper学习第五期--ZooKeeper管理分布式环境中的数据
  12. 25. JavaScript PopupAlert
  13. hosts文件是什么? 以及在各个系统中(Windows、Mac、Linux)的hosts文件在哪里?
  14. 即时通讯软件会取代电子邮件吗?
  15. windows系统扩展C盘的工具推荐(解决了C盘和压缩卷不相邻无法扩展C盘问题)
  16. 实现相册功能 java_javaWEB实现相册管理的简单功能
  17. [美国签证]准备材料及面签过程
  18. OCR技术(大批量生成文字训练集)
  19. 维度建模和范式建模对比
  20. 海量高性能列式数据库HiStore技术架构解析

热门文章

  1. ASCII 编码对照表
  2. 静态程序分析chapter2 - IR(Jimple) 和 CFG
  3. JavaScript夯实基础系列(二):闭包
  4. setTimeOut函数和setInterval函数
  5. OOD知识---对OOA\OOD\OOP思想
  6. CvArr、Mat、CvMat、IplImage、BYTE转换(总结而来)
  7. Java 多线程断点下载文件_详解
  8. Intel X86 CPU系列的寄存器
  9. CSS块级元素和行内元素
  10. 关于 DOM 操作的几个类型