linux--网络编程(8)
来源:互联网 发布:制造业软件 编辑:程序博客网 时间:2024/06/06 15:47
通信协议(OSI、TCP/IP)
OSI协议(七层网络协议)
下三层
1物理层(类似网卡(接收传输数据))
2链路层(解析数据)
3网络层(选择数据传送)
高四层
4传输层(提供端对端接口(传输数据))
5会话层(会话x,(解除或建立联系))
6表示层(表示x,(加密、转换))
7应用层(行动x(展示网络服务))TCP/IP协议(四层协议)
- TCP/IP 具有两个主要功能。第一是IP 在网络之间(有时在个别网络内部)提供路由选择。第二是TCP 将TP 传递的数据传送的接收主机那的适当的处理部件。
- 套接字(类似SIM卡)
套接字有三种类型:流式套接字(SOCK_STREAM),数据报套接字(SOCK_DGRAM)及原始套接字 - 流式套接字
流式的套接字可以提供可靠的、面向连接的通讯流。如果你通过流式套接字发送了顺序的数据:“1”、“2”。那么数据到达远程时候的顺序也是“1”、“2”。采用TCP协议
数据报套接字
一种无连接的服务,数据通过相互独立的报文进行传输,是无序的,并且不保证可靠,无差错,使用者数据报协议UDP(User Datagram Protocol )
原始套接字
主要用于一些协议的开发,可以进行比较底层的操作
TCP协议:
三次握手:请求连接–>授权—>连接
四次关闭:客户端请求关闭—>服务端可以关了—>客户端关了—>服务端也关了
socket基本函数
htons() 主机字节顺序转换为网络字节顺序(对无符号短型进行操作4 bytes)
htonl() 主机字节顺序转换为网络字节顺序(对无符号长型进行操作8 bytes)
ntohs() 网络字节顺序转换为主机字节顺序(对无符号短型进行操作4 bytes)
ntohl() 网络字节顺序转换为主机字节顺序(对无符号长型进行操作8 bytes)
close() 关闭套接字,任何有关对套接字描述符进行读和写的操作都会接收到一个错误。
shutdown() 允许你进行单向的关闭操作,或是全部禁止掉(0不接 1不发 2全关)
setsockopt() 、 getsockopt() 设置和获取套接字的属性
getpeername() 获取连接上的远程信息
socket(TCP/IP)代码
- IP和主机地址处理
/******** IP和主机地址 *************/#include <stdio.h>#include <stdlib.h>#include <netdb.h>#include <netinet/in.h>/*struct sockaddr_in{ //“in” 代表 “Internet” short int sin_family; // Internet地址族 unsigned short int sin_port; // 端口号 struct in_addr sin_addr; // Internet地址 unsigned char sin_zero[8]; // 添0(和struct sockaddr一样大小)};*/int main(int argc, char *argv[]){ struct hostent *host; //域名解析成IP host = gethostbyname(argv[1]); //字符串转成整型inet_addr() printf("%d\n", inet_addr("166.111.69.52")); printf("hostname == %s\n", host->h_name); //整机转成字符串inet_ntoa() printf("ip == %s\n", inet_ntoa(((struct in_addr *)(host->h_addr_list[0]))->s_addr)); return 0;}
- 2.socket函数
//1.网络协议一般是AF_INET 2.TCP(SOCK_STREAM)或者UDP(SOCK_STREAM)3.一般为0//int socket(int family , int type , int protocol); ------买电话机//1.电话机2.绑定端口号码 3.//int bind (int sockfd , struct sockaddr *my_addr , int addrlen) ;--------插线(2绑定到1上)//1.电话机 2.同时监听的个数(一般5--10)//int listen(int sockfd, int backlog); --------待机(监听)//1.电话机 2.传过来的地址 3.//int accept(int sockfd, void *addr, int *addrlen) ----------接听
- 3.基本socket的建立
/***********基本步骤(服务端.c)***********/#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <sys/types.h>#include <netinet/in.h>#include <sys/socket.h>#include <sys/wait.h>#define PORT 4999int main(int argc, char *argv[]){ int sfd; int accept_fd; struct sockaddr_in addr; struct sockaddr_in client_addr; char buf[128]; int size; int ret; //创建socket sfd = socket(AF_INET, SOCK_STREAM, 0); memset(&addr, 0, sizeof(struct sockaddr_in)); //绑定端口 printf("===create socket===\n"); addr.sin_family = AF_INET; addr.sin_port = htons(PORT); addr.sin_addr.s_addr = INADDR_ANY; printf("===bind===\n"); bind(sfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)); //监听 printf("===listen===\n"); listen(sfd, 10); //接收 printf("===accept===\n"); size = sizeof(struct sockaddr); accept_fd = accept(sfd, (struct sockaddr *)&client_addr, &size); printf("===send===\n"); //读取或输出 memset(buf, 0, sizeof(buf)); strcpy(buf, "abc"); ret = send(accept_fd, buf,strlen(buf),0); printf("==ret is:%d\n", ret); sleep(10); close(accept_fd); close(sfd); return 0; return 0;}----------------------------------------------/***********基本步骤(客户端.c)***********/#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <sys/types.h>#include <netinet/in.h>#include <sys/socket.h>#include <sys/wait.h>int main(int argc, char *argv[]){ int sfd; int accept_fd; struct sockaddr_in addr; struct sockaddr_in client_addr; char buf[128]; int ret; sfd = socket(AF_INET, SOCK_STREAM, 0); memset(&addr, 0, sizeof(struct sockaddr_in)); memset(&addr, 0, sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; addr.sin_port = htons(4999); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); ret = connect(sfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)); memset(buf, 0, 128); ret = recv(sfd, buf, 128, 0); printf("===buf===:%s\n", buf); close(sfd); return 0;}
- 3.复杂点的socket
/************实现多个客户端对一个客户端(服务端.C)*************/#include<stdio.h>#include<stdlib.h>#include<errno.h>#include<string.h>#include<netdb.h>#include<unistd.h>#include<sys/types.h>#include<sys/socket.h>#include<sys/time.h>#include<sys/un.h>#include<sys/ioctl.h>#include<sys/wait.h>#include<netinet/in.h>#include<arpa/inet.h>#define SERVPORT 1234#define BACKLOG 20#define MAX_CON_NO 10#define MAX_DATA_SIZE 1024void *deal_msg(void *arg){ int newfd; char sendBuf[MAX_DATA_SIZE], recvBuf[MAX_DATA_SIZE]; int recvBytes, sendBytes; pthread_detach(pthread_self()); newfd = *(int *)arg; while(1) { /* 接收*/ if((recvBytes = recv(newfd, recvBuf, MAX_DATA_SIZE, 0)) == -1){ perror("fail to receive datas"); exit(1); } printf("client :%s\n", recvBuf); memset(recvBuf, 0x00, MAX_DATA_SIZE); /* 发送*/ printf("server:"); gets(sendBuf); if((sendBytes = send(newfd, sendBuf, strlen(sendBuf), 0)) != strlen(sendBuf)){ perror("fail to receive datas"); exit(1); } printf("(success to send data!)\n"); memset(sendBuf, 0x00, MAX_DATA_SIZE); } close(newfd); return NULL;}int main(int argc, char *argv[]) { struct sockaddr_in serverSockaddr, clientSockaddr; int sinSize, recvBytes, sendBytes; pthread_t tid; int sockfd, clientfd; //char mac[6]; if(argc != 1) { printf("usage:./server\n"); exit(1); } /*establish a socket*/ if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("fail to establish a socket"); exit(1); } printf("Success to establish a socket...(sockfd = %d)\n", sockfd); /*init sockaddr_in*/ serverSockaddr.sin_family = AF_INET; serverSockaddr.sin_port = htons(SERVPORT); serverSockaddr.sin_addr.s_addr = htonl(INADDR_ANY); bzero(&(serverSockaddr.sin_zero), 8); int on = 1; /*设置和套接字的属性*/ setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); /*bind socket*/ if(bind(sockfd, (struct sockaddr *)&serverSockaddr, sizeof(struct sockaddr))== -1) { perror("fail to bind"); exit(1); } printf("Success to bind the socket...\n"); /*listen on the socket*/ if(listen(sockfd, BACKLOG) == -1) { perror("fail to listen"); exit(1); } printf("Success to listen on the socket...\n"); while(1) { sinSize = sizeof(struct sockaddr_in); /*accept a client's request*/ if ((clientfd = accept(sockfd, (struct sockaddr *)&clientSockaddr, &sinSize)) == -1) { perror("fail to accept"); exit(1); } printf("success to accept=======\n"); /*改变打印颜色*/ printf("\033[40;32mWelcome to join %s!\033[1m\n", inet_ntoa(clientSockaddr.sin_addr)); /* 创建线程实现信号传递 */ pthread_create(&tid, NULL, deal_msg, &clientfd); }}-----------------------------------------------------------/************实现多个客户端对一个客户端(客户端.C)*************/#include<stdio.h>#include<stdlib.h>#include<errno.h>#include<string.h>#include<netdb.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#define SERVPORT 1234#define MAX_DATA_SIZE 1024int main(int argc, char *argv[]){ int sockfd, sendBytes,recvBytes; char sendBuf[MAX_DATA_SIZE],recvBuf[MAX_DATA_SIZE]; struct hostent *host; struct sockaddr_in servAddr; if(argc != 2) { fprintf(stderr,"usage:./client [hostname]"); exit(1); } /*translate the address*/ if((host = gethostbyname(argv[1])) == NULL) { perror("fail to get host by name"); exit(1); } printf("Success to get host by name...\n"); /*establish a socket*/ if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("fail to establish a socket"); exit(1); } printf("Success to establish a socket...\n"); /*init sockaddr_in*/ servAddr.sin_family = AF_INET; servAddr.sin_port = htons(SERVPORT); servAddr.sin_addr = *((struct in_addr *)host -> h_addr); bzero(&(servAddr.sin_zero), 8); /*connect the socket*/ if(connect(sockfd, (struct sockaddr *)&servAddr, sizeof(struct sockaddr_in)) == -1) { perror("fail to connect the socket"); goto _exit; } printf("Success to connect the socket...\n"); printf("\033[40;32mWelcome to join %s!\033[1m\n", inet_ntoa(servAddr.sin_addr)); //include color set while(1) { /*send datas to server*/ printf("Client:"); gets(sendBuf); if ((sendBytes = send(sockfd, sendBuf, strlen(sendBuf),0)) != strlen(sendBuf)){ perror("fail to send data!\n"); goto _exit; } printf("(success to send data!)\n"); memset(sendBuf, 0x00, MAX_DATA_SIZE); /*recive datas to server*/ if ((recvBytes = recv(sockfd, recvBuf, MAX_DATA_SIZE, 0)) == -1){ perror("fail to send data!\n"); goto _exit; } printf("server :%s\n", recvBuf); memset(recvBuf, 0, MAX_DATA_SIZE); }_exit: close(sockfd);}
- 4.无限大小的数据传输socket
/*********服务端.c***************/#include<stdio.h>#include<stdlib.h>#include<errno.h>#include<string.h>#include<netdb.h>#include<unistd.h>#include<sys/types.h>#include<sys/socket.h>#include<sys/time.h>#include<sys/un.h>#include<sys/ioctl.h>#include<sys/wait.h>#include<netinet/in.h>#include<arpa/inet.h>#include "comm.h"#include "lst.h"#define SERVPORT 1234#define BACKLOG 20#define MAX_CON_NO 10#define MAX_DATA_SIZE 1024void *deal_msg(void *arg){ int newfd; char http_buf[1500]; char sendBuf[MAX_DATA_SIZE], recvBuf[MAX_DATA_SIZE]; int recvBytes, sendBytes; msg_head_t *msg; char *msgbuf; char buf[64]; int ret; pthread_detach(pthread_srlf()); newfd = *(int *)arg; while(1) { memset(buf, 0, 64); memset(&msg, 0 sizeof(msg_head_t)); ret = recv(newfd, &msg, sizeof(msg_head_t), 0); msg = (msg_head_t *)buf; recvBytes = msg.len; printf("======recvBytes is :%d,%d\n", msg->len, ret); msgbuf = malloc(recvBytes); memset(msgbuf, 0, recvBytes); recv(newfd, msgbuf, recvBytes, 0); printf("==recv msgbuf:%s\n", msgbuf); free(msgbuf); break; } close(newfd); return NULL;}int main(int argc, char *argv[]) { struct sockaddr_in serverSockaddr, clientSockaddr; int sinSize, recvBytes, sendBytes; pthread_t tid; int sockfd, clientfd; int fdmax; int ret; int i = 0; char mac[6]; fd_set readfs; sock_array_t *pos, *pon; if(argc != 1) { printf("usage:./server\n"); exit(1); } /*establish a socket*/ if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("fail to establish a socket"); exit(1); } printf("Success to establish a socket...(sockfd = %d)\n", sockfd); /*init sockaddr_in*/ serverSockaddr.sin_family = AF_INET; serverSockaddr.sin_port = htons(SERVPORT); serverSockaddr.sin_addr.s_addr = htonl(INADDR_ANY); bzero(&(serverSockaddr.sin_zero), 8); int on = 1; /*设置和套接字的属性*/ setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); /*bind socket*/ if(bind(sockfd, (struct sockaddr *)&serverSockaddr, sizeof(struct sockaddr))== -1) { perror("fail to bind"); exit(1); } printf("Success to bind the socket...\n"); /*listen on the socket*/ if(listen(sockfd, BACKLOG) == -1) { perror("fail to listen"); exit(1); } printf("Success to listen on the socket...\n"); while(1) { sinSize = sizeof(struct sockaddr_in); /*accept a client's request*/ if ((clientfd = accept(sockfd, (struct sockaddr *)&clientSockaddr, &sinSize)) == -1) { perror("fail to accept"); exit(1); } printf("success to accept=======\n"); /*改变打印颜色*/ printf("\033[40;32mWelcome to join %s!\033[1m\n", inet_ntoa(clientSockaddr.sin_addr)); /* 创建线程实现信号传递 */ pthread_create(&tid, NULL, deal_msg, &clientfd); } return 0;}/*********客户端.c***************/#include<stdio.h>#include<stdlib.h>#include<errno.h>#include<string.h>#include<netdb.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#include "comm.h"#define SERVPORT 1234#define MAX_DATA_SIZE 3096 int main(int argc, char *argv[]){ int sockfd, sendBytes,recvBytes; char sendBuf[MAX_DATA_SIZE],recvBuf[MAX_DATA_SIZE]; struct hostent *host; struct sockaddr_in servAddr; msg_head_t *msg; // int ret; if(argc != 2) { fprintf(stderr,"usage:./client [hostname]"); exit(1); } /*translate the address*/ if((host = gethostbyname(argv[1])) == NULL) { perror("fail to get host by name"); exit(1); } printf("Success to get host by name...\n"); /*establish a socket*/ if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("fail to establish a socket"); exit(1); } printf("Success to establish a socket...\n"); /*init sockaddr_in*/ servAddr.sin_family = AF_INET; servAddr.sin_port = htons(SERVPORT); servAddr.sin_addr = *((struct in_addr *)host -> h_addr); bzero(&(servAddr.sin_zero), 8); /*connect the socket*/ if(connect(sockfd, (struct sockaddr *)&servAddr, sizeof(struct sockaddr_in)) == -1) { perror("fail to connect the socket"); goto _exit; } printf("Success to connect the socket...\n"); printf("\033[40;32mWelcome to join %s!\033[1m\n", inet_ntoa(servAddr.sin_addr)); //include color set while(1) { /*send datas to server*/ printf("Client:"); gets(sendBuf); sendBytes = strlen(sendBuf); msg = (msg_head_t *)malloc(sizeof(msg_head_t) + sendBytes + 1); memset(msg, 0, sizeof(msg_head_t) + sendBytes + 1); msg->len = sendBytes; printf("===msg_len [%d]\n", msg->len); strncpy(msg->data, sendBuf, strlen(sendBuf)); printf("==data is: %s\n", msg->data); send(sockfd, msg, sizeof(msg_head_t) + msg->len + 1, 0); }_exit: close(sockfd);}/***************结构体头文件.h**********/#ifndef _COMM_H_#define _COMM_H_typedef struct msg_head_s{ int type; int len; char data[0];}msg_head_t;#endif
I/O多路复用
- 作用:它能同时等待多个文件描述符,而这些文件描述符(套接字描述符)其中的任意一个进入读就绪状态。处理多个套接字使用
- 基本函数
Select()函数可以帮助你同时监视许多套接字。它会告诉你哪一个套接字已经可以读取数据,哪个套接字已经可以写入数据,甚至你可以知道哪个套接字出现了错误 - 相关宏
FD_ZERO(fd_set *set)将一个文件描述符集合清零
FD_SET(int fd, fd_set *set)将文件描述符fd 加入集合set 中。
FD_CLR(int fd, fd_set *set)将文件描述符fd 从集合set 中删除.
FD_ISSET(int fd, fd_set *set)测试文件描述符fd 是否存在于文件描述符set 中.
0 0
- linux--网络编程(8)
- Linux--网络编程(一)网络介绍
- Linux网络编程读书笔记(8)
- Linux网络编程(一)
- linux网络编程(socket)
- linux网络编程(笔记)
- 网络编程入门(linux)
- linux网络编程(一)
- linux网络编程(2)
- linux网络编程(转载)
- linux网络编程(一)
- Linux Socket编程(网络)
- Linux网络编程(三)
- Linux网络编程(四)
- linux网络编程(1)
- linux网络编程(2)
- Linux网络编程(一)
- Linux网络编程(二)
- 问题 S 幸运数
- What is the read parameter in @ViewChild for
- Kendo UI常用示例汇总(十七)
- 去掉超链接文字点击后的灰色框
- 堆大小设置
- linux--网络编程(8)
- history.back与history.go
- 问题 R 时间转换
- JSPatch热修复的使用的那些深坑
- 前端背景图片走样
- org.hibernate.AnnotationException: No identifier specified for entity
- unix的AIX,xlc生成动态库后为什么还要用ln -s 对*.so动态库生成软连接为*.a
- 堆排序
- CentOS6.7设置程序开机自启动