linux中网络编程<1>
1 网络编程API
(1)网络层的ip地址可以唯一标识网络中的主机,传输层通过协议+端口唯一标识主机中的应用程序。这样以来使用三元组(地址,协议,端口)标识网络的进程。
(2)socket--->插槽(低俗的哈哈哈哈),看作文件描述符,Linux基本哲学一切皆文件,那么是不是也可以读写关闭这样的习惯性操作呢。对了,差不多的啦。
(3)来看看tcp交互流程
ok具体看看各个函数
第一个:int socket(int domain,int type,int protocol)
参数介绍:
domain:协议域,决定了socekt地址类型
type:socket类型.
protocol:指定协议。
调用这个函数返回的socket描述符就在协议族的空间中,但是没有一个具体的地址,所以咱们给予它地址就有勒bind
第二个:int bind(int socketfd,const struct sockaddr *addr,socklen_t addrlen)
参数介绍
addr:指向半丁给sockfd的协议地址。根据创建socekt时的地址协议族的不同而不同
第三个和第四个:listen connect
监听 客户端呢就链接撒
第五个:accept
当客户端发送了链接请求以后,就开始接受。都接受了就可以开始交流了嘛---->进行io操作。
注意:accept成功,返回值由内核自动生成一个新的描述符哦。
第六个,第六组吧
read() write()
recv() send()
readv() writev()
recvmsg() sendmsg()
recvfrom() sendto()
read读取成功会放回实际读取的字节数。0标识读到我呢见的末尾。
2 来一个例子
1 //client.cpp 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<errno.h> 6 #include<sys/types.h> 7 #include<sys/socket.h> 8 #include<netinet/in.h> 9 #include<arpa/inet.h> 10 #include<unistd.h> 11 #define MAXLINE 4096 12 13 int main(int argc, char** argv){ 14 int sockfd, n; 15 char recvline[4096], sendline[4096]; 16 struct sockaddr_in servaddr; 17 18 if( argc != 2){ 19 printf("usage: ./client <ipaddress>\n"); 20 return 0; 21 } 22 23 if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){ 24 printf("create socket error: %s(errno: %d)\n", strerror(errno),errno); 25 return 0; 26 } 27 28 memset(&servaddr, 0, sizeof(servaddr)); 29 servaddr.sin_family = AF_INET; 30 servaddr.sin_port = htons(6666); 31 if( inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0){ 32 printf("inet_pton error for %s\n",argv[1]); 33 return 0; 34 } 35 36 if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){ 37 printf("connect error: %s(errno: %d)\n",strerror(errno),errno); 38 return 0; 39 } 40 41 printf("send msg to server: \n"); 42 fgets(sendline, 4096, stdin); 43 if( send(sockfd, sendline, strlen(sendline), 0) < 0){ 44 printf("send msg error: %s(errno: %d)\n", strerror(errno), errno); 45 return 0; 46 } 47 close(sockfd); 48 return 0; 49 }
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<errno.h> 5 #include<sys/types.h> 6 #include<sys/socket.h> 7 #include<netinet/in.h> 8 #include<unistd.h> 9 10 #define MAXLINE 4096 11 12 int main(int argc, char** argv){ 13 int listenfd, connfd;//这里有两个 一个是创建套接字描述符 一个是建立连接后的描述符哈 14 struct sockaddr_in servaddr; 15 char buff[4096]; 16 int n; 17 18 if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){ 19 printf("create socket error: %s(errno: %d)\n",strerror(errno),errno); 20 return 0; 21 } 22 23 memset(&servaddr, 0, sizeof(servaddr)); 24 servaddr.sin_family = AF_INET; 25 servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 26 servaddr.sin_port = htons(6666); 27 28 if( bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){ 29 printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno); 30 return 0; 31 } 32 33 if( listen(listenfd, 10) == -1){ 34 printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno); 35 return 0; 36 } 37 38 printf("======waiting for client's request======\n"); 39 while(1){ 40 if( (connfd = accept(listenfd, (struct sockaddr*)NULL, NULL)) == -1){ 41 printf("accept socket error: %s(errno: %d)",strerror(errno),errno); 42 continue; 43 } 44 n = recv(connfd, buff, MAXLINE, 0); 45 buff[n] = '\0';//注意了 要输出字符串 后面加上这个玩意哦 46 printf("recv msg from client: %s\n", buff); 47 close(connfd); 48 } 49 close(listenfd); 50 return 0; 51 }
1 all:server client 2 server:server.o 3 g++ -g -o server server.o 4 client:client.o 5 g++ -g -o client client.o 6 server.o:server.cpp 7 g++ -g -c server.cpp 8 client.o:client.cpp 9 g++ -g -c client.cpp 10 clean:all 11 rm all
先运行./server 然后./client 127.0.0.1如下图所示
ok 热身下了,什么字节序之类的下一篇在总结勒。加油。。。。