届毕业设计代做网站,软件开发5个过程,明星网页设计模板图片,wap网站开发培训Linux C网络编程——API 宗旨#xff1a;技术的学习是有限的#xff0c;分享的精神的无限的。 一、基本socket函数 Linux系统是通过提供套接字(socket)来进行网络编程的。网络的socket数据传输是一种特殊的I/O,socket也是一种文件描述符。socket也有一个类似于打开文件的函数…Linux C网络编程——API 宗旨技术的学习是有限的分享的精神的无限的。 一、基本socket函数 Linux系统是通过提供套接字(socket)来进行网络编程的。网络的socket数据传输是一种特殊的I/O,socket也是一种文件描述符。socket也有一个类似于打开文件的函数socket(),调用socket(),该函数返回一个整型的socket的描述符随后的连接建立、数据传输等操作也都是通过该socket实现。
1、socket函数 ——创建套接字
1函数原型 int socket(int domain, int type, int protocol);
2函数参数 domain指明所使用的协议族通常为PF_INET表示TCP/IP协议 type参数指定socket的类型基本上有三种数据流套接字、数据报套接字、原始套接字 protocol通常赋值0。
3返回值 调用成功返回socket文件描述符失败返回1并设置errno 两个网络程序之间的一个网络连接包括五种信息通信协议、本地协议地址、本地主机端口、远端主机地址和远端协议端口。socket数据结构中包含这五种信息。
2、bind函数 ——将套接字和指定的端口相连
1函数原型 struct sockaddr_in
{short intsin_family;unsignedshort int sin_port;structin_addr sin_addr;unsignedchar sin_zero[8];
}; // addrlen为sockaddr的长度。int bind(int sock_fd, struct sockaddr_in *my_addr, int addrlen); 2函数参数 sock_fd是调用socket函数返回值 my_addr是一个指向包含有本机IP地址及端口号等信息的sockaddr类型的指针 struct sockaddr_in结构类型是用来保存socket信息的。
3返回值 成功返回0否则返回1并置errno。
3、connect函数 ——客户端发送服务请求
1函数原型 int connect(int sock_fd, struct sockaddr*serv_addr,int addrlen);
2函数参数 sock_fd 是socket函数返回的socket描述符 serv_addr是包含远端主机IP地址和端口号的指针 addrlen是结构sockaddr_in的长度。
3返回值 成功返回0否则返回1并置errno。
4、listen函数 ——等待指定的端口的出现客户端连接
1函数原型 int listen(int sock_fd int backlog);
2函数原型 sock_fd 是socket()函数返回值 backlog指定在请求队列中允许的最大请求数
3返回值 调用成功返回0否则返回1并置errno.
5、accecpt函数 ——用于接受客户端的服务请求
1函数原型 int accept(int sock_fd, struct sockadd_in* addr, int addrlen);
2函数参数 sock_fd是被监听的socket描述符 addr通常是一个指向sockaddr_in变量的指针 addrlen是结构sockaddr_in的长度。
3返回值 成功返回新的套接字描述符失败返回1并置errno。
6、write函数 ——write函数将buf中的nbytes字节内容写入文件描述符
1函数原型 ssize_t write(int fd,const void *buf,size_t nbytes);
2函数参数 fd套接字 buf要写入的数据 nbytes字节数
3返回值 成功时返回写的字节数.失败时返回-1. 并设置errno变量.
在网络程序中,当我们向套接字文件描述符写时有俩种可能 (1)write的返回值大于0,表示写了部分或者是全部的数据.
(2)返回的值小于0,此时出现了错误.需要根据错误类型来处理. 如果错误为EINTR表示在写的时候出现了中断错误. 如果错误为EPIPE表示网络连接出现了问题.
7、read函数 ——read函数是负责从fd中读取内容
1函数原型 ssize_t read(int fd,void *buf,size_t nbyte)
2函数参数 fd套接字 buf存放要读出的数据 nbytes字节数
3返回值 当读成功时,read返回实际所读的字节数,如果返回的值是0 表示已经读到文件的结束了,小于0表示出现了错误。如果错误为EINTR说明读是由中断引起的如果错误是ECONNREST表示网络连接出了问题。
8、close函数 ——关闭socket
1函数原型 int close(sock_fd);
2函数参数 sock_fd套接字
3返回值 函数运行成功返回0否则返回-1。 二、socket编程的其他函数说明
1、网络字节顺序及其转换函数
1网络字节顺序 每一台机器内部对变量的字节存储顺序不同而网络传输的数据是一定要统一顺序的。所以对内部字节表示顺序与网络字节顺序不同的机器一定要对数据进行转换从程序的可移植性要求来讲就算本机的内部字节表示顺序与网络字节顺序相同也应该在传输数据以前先调用数据转换函数以便程序移植到其它机器上后能正确执行。真正转换还是不转换是由系统函数自己来决定的。
2有关的转换函数 unsigned short int htonsunsigned short int hostshort主机字节顺序转换成网络字节顺序对无符号短型进行操作4bytes
unsigned long int htonlunsigned long int hostlong主机字节顺序转换成网络字节顺序对无符号长型进行操作8bytes
unsigned short int ntohsunsigned short int netshort网络字节顺序转换成主机字节顺序对无符号短型进行操作4bytes
unsigned long int ntohlunsigned long int netlong网络字节顺序转换成主机字节顺序对无符号长型进行操作8bytes
注以上函数原型定义在netinet/in.h里 2、IP地址转换 有三个函数将数字点形式表示的字符串IP地址与32位网络字节顺序的二进制形式的IP地址进行转换
1unsigned long int inet_addr(constchar * cp)该函数把一个用数字和点表示的IP地址的字符串转换成一个无符号长整型如struct sockaddr_in ina
ina.sin_addr.s_addrinet_addr(202.206.17.101)
该函数成功时返回转换结果失败时返回常量INADDR_NONE该常量-1二进制的无符号整数-1相当于255.255.255.255这是一个广播地址所以在程序中调用iner_addr时一定要人为地对调用失败进行处理。由于该函数不能处理广播地址所以在程序中应该使用函数inet_aton。
2int inet_atonconst char * cp,struct in_addr *inp此函数将字符串形式的IP地址转换成二进制形式的IP地址成功时返回1否则返回0转换后的IP地址存储在参数inp中。
3char * inet_ntoastruct in-addr in将32位二进制形式的IP地址转换为数字点形式的IP地址结果在函数返回值中返回返回的是一个指向字符串的指针。
3、字节处理函数 Socket地址是多字节数据不是以空字符结尾的这和C语言中的字符串是不同的。Linux提供了两组函数来处理多字节数据一组以bbyte开头是和BSD系统兼容的函数另一组以mem内存开头是ANSI C提供的函数。
以b开头的函数有
1void bzerovoid * s,int n将参数s指定的内存的前n个字节设置为0通常它用来将套接字地址清0。
2void bcopyconst void * srcvoid * destint n从参数src指定的内存区域拷贝指定数目的字节内容到参数dest指定的内存区域。
3int bcmpconst void * s1const void * s2int n比较参数s1指定的内存区域和参数s2指定的内存区域的前n个字节内容如果相同则返回0否则返回非0。
注以上函数的原型定义在strings.h中。
以mem开头的函数有
1void * memsetvoid * sint csize_t n将参数s指定的内存区域的前n个字节设置为参数c的内容。
2void * memcpyvoid * destconst void * srcsize_t n功能同bcopy区别函数bcopy能处理参数src和参数dest所指定的区域有重叠的情况memcpy则不能。
4int memcmpconst void * s1const void * s2size_t n比较参数s1和参数s2指定区域的前n个字节内容如果相同则返回0否则返回非0。
注以上函数的原型定义在string.h中。 三、程序说明 本使用tcp协议进行通信服务端进行监听在收到客户端的连接后发送数据给客户端客户端在接受到数据后打印出来然后关闭。
服务端socket -- bind -- listen -- accept -- read/write -- close
客户端socket -- connect -- read/write -- close /************************************************************************* File Name: client.c Author: libang Mail: 1838039453qq.com Created Time: 2014年04月03日 星期日 02时59分37秒************************************************************************/#include stdio.h
#include string.h
#include errno.h
#include sys/socket.h
#include resolv.h
#include stdlib.h
#include netinet/in.h
#include unistd.h
#include arpa/inet.h#define MAXBUF 1024int main(int argc,char *argv[])
{pid_t pid;int socket_fd,len;struct sockaddr_in dest;char buffer[MAXBUF];if(argc ! 3){printf(error format,it must be:\n\t\t%s IP port\n,argv[0]);exit(EXIT_FAILURE);}if((socket_fd socket(AF_INET,SOCK_STREAM,0)) 0){perror(socket);exit(EXIT_FAILURE);}printf(Socket created!\n);bzero(dest,sizeof(dest));dest.sin_family AF_INET;dest.sin_port htons(atoi(argv[2]));if(inet_aton(argv[1],(struct in_addr *)dest.sin_addr.s_addr) 0){perror(argv[1]);exit(errno);}if(connect(socket_fd,(struct sockaddr *)dest,sizeof(dest)) -1){perror(connect);exit(errno);}printf(Server connected!\n);if(-1 (pid fork())){perror(fork);exit(EXIT_FAILURE);}else if(pid 0){while(1){bzero(buffer,MAXBUF);len recv(socket_fd,buffer,MAXBUF,0);if(len 0){printf(recv successful:%s,%d byte recv\n,buffer,len);}else if(len 0){perror(recv);break;}else{printf(the other one close,quit\n);break;}}}else{while(1){bzero(buffer,MAXBUF);//printf(please send message to send:);fgets(buffer,MAXBUF,stdin);if(!strncasecmp(buffer,quit,4)){printf(I will quit!\n);break;}len send(socket_fd,buffer,strlen(buffer) - 1,0);if(len 0){perror(send);break;}}}close(socket_fd);return 0;
}/************************************************************************* File Name: server.c Author: libang Mail: 1838039453qq.com Created Time: 2016年04月03日 星期日 20时57分48秒************************************************************************/#include stdio.h
#include string.h
#include errno.h
#include sys/socket.h
#include resolv.h
#include stdlib.h
#include netinet/in.h
#include arpa/inet.h
#include unistd.h#define MAXBUF 1024int main(int argc,char *argv[])
{int socket_fd,new_fd;socklen_t len;struct sockaddr_in my_addr,their_addr;pid_t pid;unsigned int myport,list_num;char buf[MAXBUF];if(argv[2]){myport atoi(argv[2]);}elsemyport 7575;if(argv[3]){list_num atoi(argv[3]);}elselist_num 10;if((socket_fd socket(AF_INET,SOCK_STREAM,0)) -1){perror(socket);exit(EXIT_FAILURE);}bzero(my_addr,sizeof(my_addr));my_addr.sin_family AF_INET;my_addr.sin_port htons(myport);if(argv[1]){my_addr.sin_addr.s_addr inet_addr(argv[1]);}elsemy_addr.sin_addr.s_addr INADDR_ANY;len sizeof(struct sockaddr);if(bind(socket_fd,(struct sockaddr *)my_addr,len) -1){perror(bind);exit(EXIT_FAILURE);}if(listen(socket_fd,list_num) -1){perror(listen);exit(EXIT_FAILURE);}printf(wait for connect!\n);if((new_fd accept(socket_fd,(struct sockaddr *)their_addr,len)) -1){perror(accept);exit(EXIT_FAILURE);}elseprintf(server:got connection from %s,port %d,socket %d\n,inet_ntoa(their_addr.sin_addr),ntohs(their_addr.sin_port),new_fd);if(-1 (pid fork())){perror(fork);exit(EXIT_FAILURE);}else if(pid 0){while(1){bzero(buf,MAXBUF);//printf(input the message to send:);fgets(buf,MAXBUF,stdin);if(!strncasecmp(buf,quit,4)){printf(I will close the connect!\n);break;}len send(new_fd,buf,strlen(buf) - 1,0);if(len 0){printf(message %s send failure!error code is %d error message is %s\n,buf,errno,strerror(errno));break;}}}else{while(1){bzero(buf,MAXBUF);len recv(new_fd,buf,MAXBUF,0);if(len 0){printf(message recv successful!:%s,%dByte recv\n,buf,len);}else if(len 0){printf(recv failure!errno code is %d,errno message is ‘%s\n,errno,strerror(errno));break;}else{printf(the other one close quit!\n);break;}}}close(new_fd);close(socket_fd);return 0;
}
gcc -o server server.c gcc -o client client.c
./server 192.168.207.129 7575 5 ./client 192.168.207.129 7575