socket网络编程
第十章、socket网络编程
1.主机字节与网络字节序
2.socket地址结构
3.TCP编程流程与编程接口
1》int socket(),创建套接字,用于监听客户端的连接
2》int listen()的第二个参数很重要!
listen的第二个参数指定内核分配的维护已完成链接的客户端的个数
内核分配两个队列:
1.正在完成链接的队列
2.已经完成链接的队列
3》int accept()方法:accept不是和一个客户端完成链接,只是从内核维护的已完成的链接队列中获取一个连接而已!!!
4》int close();//参数是链接socket,意味着关闭的是一个与客户端的链接
5》int close();//参数是监听socket,意味着服务器关闭
选用端口号listen方法的第二个参数
==backlog:内核需要创建的–维护已完成的客户连接的队列的大小=服务器端代码
1.#include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4#include<unistd.h>
5 #include<assert.h>
6 #include<sys/socket.h>
7 #include<sys/types.h>
8 #include<arpa/inet.h>
9 #include<netinet/in.h>
10
11 int main()
12 {
13 //int socket(int domain,int type,int protocol);
14 //type: SOCK_STREAM == tcp; SOCK_DGRAM ==udp;
15 int listenfd=socket(AF_INET,SOCK_STREAM,0);
16 assert(listenfd != -1);
17
18 struct sockaddr_in ser_addr;
19 ser_addr.sin_family=AF_INET;
20 ser_addr.sin_port=htons(6000) ;//给定程序所选择的端口号 -------》 主机字节序、网络字节序
21 ser_addr.sin_addr.s_addr=inet_addr("127.0.0.1");//给定服务器的IP地址
22
23 int res=bind(listenfd,(struct sockaddr*)&ser_addr,sizeof(ser_addr));
24 assert(res!=-1);//bind失败的原因:IP地址不对or端口号被占用或无权限
25
26 //listen方法的第二个参数backlog指定内核创建的用于维护已完成连接的队列大小
27 res = listen(listenfd,5);
28 assert(res!=-1);
29
30
31 //循环获取客户端的链接
32 while(1)
33 {
34 struct sockaddr_in cli_addr;
35 socklen_t len=sizeof(cli_addr);
36 int c=accept(listenfd,(struct sockaddr*)&cli_addr,&len);
37 if(c==-1)
38 {
39 printf("accept error\n");
40 continue;
41 }
42
43 //循环与获取的客户端链接完成交互过程
44 while(1)
45 {
46 char buff[128]={0};
47 int n=recv(c,buff,127,0);//如果没有数据会阻塞 类似于read,最后是标志位
48 if(n<=0)
49 {
50 break;
51 }
52
53 printf("%d : %s\n",c,buff);
54
55 n=send(c,"OK",2,0); //和write方法一样
56 if(n<=0)
57 {
58 break;//关闭的是客户端
59 }
60 }
61 close(c);//关闭的是客户端
62 }
63 close(listenfd);
64 }
客户端代码
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4 #include<unistd.h>
5 #include<assert.h>
6
7 #include<sys/socket.h>
8 #include<sys/types.h>
9 #include<arpa/inet.h>
10 #include<netinet/in.h>
11
12 int main()
13 {
14 int sockfd = socket(AF_INET,SOCK_STREAM,0);
15 assert(sockfd != -1);
16
17 //connect第二个参数需要指定服务器程序的地址信息
18 struct sockaddr_in ser_addr;
19 ser_addr.sin_family=AF_INET;
20 ser_addr.sin_port = htons(6000); //主机转网络
21 ser_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
22
23 int res=connect(sockfd,(struct sockaddr*)&ser_addr,sizeof(ser_addr));
24 assert(res != -1);
25
26 while(1)
27 {
28 printf("please input:");
29 char buff[128] ={0};
30 fgets(buff,127,stdin);
31
32 if(strncmp(buff,"end",3)==0)
33 {
34 break;
35 }
36
37 int n= send(sockfd,buff,strlen(buff)-1,0); //-1是去掉/n
38 if(n<=0)
39 {
40 break;
41 }
42
43 memset(buff,0,128);
44 n=recv(sockfd,buff,127,0);
45 if(n<=0)
46 {
47 break;
48 }
49 printf("recv data:%s\n",buff);
50 }
51
52 close(sockfd);
53
54 }
4.UDP编程流程与编程接口
4.1UDP服务器端代码
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4 #include<string.h>
5 #include<assert.h>
6
7 #include<sys/socket.h>
8 #include<sys/types.h>
9 #include<arpa/inet.h>
10 #include<netinet/in.h>
11
12 int main()
13 {
14 int sockfd=socket(AF_INET,SOCK_DGRAM,0);
15 assert(sockfd!=-1);
16
17 struct sockaddr_in ser_addr;
18 memset(&ser_addr,0,sizeof(ser_addr));
19 ser_addr.sin_family=AF_INET;
20 ser_addr.sin_port=htons(6000);
21 ser_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
22
23 int res=bind(sockfd,(struct sockaddr*)&ser_addr,sizeof(ser_addr));
24 assert(res!=-1);
25
26 while(1)
27 {
28 char buff[128]={0};
29 struct sockaddr_in peer_addr;
30 memset(&peer_addr,0,sizeof(peer_addr));
31 socklen_t len=sizeof(peer_addr);
32
33 int n=recvfrom(sockfd,buff,127,0,(struct sockaddr*)&peer_addr,&len);
34 if(n<=0)
35 {
36 printf("recvfrom error\n");
37 break;
38 }
39
40 printf("%s:%d -->%s\n",inet_ntoa(peer_addr.sin_addr),ntohs(peer_addr.s in_port),buff);
41 sendto(sockfd,"OK",2,0,(struct sockaddr*)&peer_addr,sizeof(peer_addr)) ;
42
43
44 }
45 close(sockfd);
46 }
4.2UDP客户端代码
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4 #include<string.h>
5 #include<assert.h>
6
7 #include<sys/socket.h>
8 #include<sys/types.h>
9 #include<arpa/inet.h>
10 #include<netinet/in.h>
11
12 int main()
13 {
14 int sockfd=socket(AF_INET,SOCK_DGRAM,0);
15 assert(sockfd!=-1);
16
17 struct sockaddr_in ser_addr;
18 memset(&ser_addr,0,sizeof(ser_addr));
19 ser_addr.sin_family=AF_INET;
20 ser_addr.sin_port=htons(6000);
21 ser_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
22
23 while(1)
24 {
25 printf("please input:");
26 char buff[128] ={0};
27
28 fgets(buff,127,stdin);
29 if(strncmp(buff,"end",3)==0)
30 {
31 break;
32 }
33
34 int n= sendto(sockfd,buff,strlen(buff)-1,0,(struct sockaddr*)&ser_addr,sizeof( ser_addr));
35 memset(buff,0,128);
36
37 if(n<=0)
38 {
39 break;
40 }
41 n=recvfrom(sockfd,buff,127,0,NULL,NULL);
42 if(n<=0)
43 {
44 break;
45 }
46 printf("recvfrom:%s\n",buff);
47 }
48 close(sockfd);
49
50 }