Socket网络编程略窥一二.. 网络原理课的课程设计
完全是看这篇文章学的, 貌似有中文版但是我点不进去
就不说两句了, 底层的东西, 全是细节, 非要概括的话可以引用原文第五章的小标题来描述这个过程
5.1. getaddrinfo()—Prepare to launch!
5.2. socket()—Get the File Descriptor!
5.3. bind()—What port am I on?
5.4. connect()—Hey, you!
5.5. listen()—Will somebody please call me?
5.6. accept()—”Thank you for calling port 3490.”
5.7. send() and recv()—Talk to me, baby!
5.8. sendto() and recvfrom()—Talk to me, DGRAM-style
5.9. close() and shutdown()—Get outta my face!
我的代码, 这是linux的, windows有点小不一样, 我不知道 :):
头文件..
1 | #include <stdio.h> |
2 | #include <string.h> |
3 | #include <sys/types.h> |
4 | #include <sys/socket.h> |
5 | #include <netdb.h> |
6 | #include <arpa/inet.h> |
7 | #include <stdlib.h> |
8 |
9 | #define MYPORT "2222" |
10 | #define BACKLOG 10 |
用Stream的:
(两个楞大的大括号…)
1 | #include "commonheader.h" |
2 |
3 | int main() { |
4 | char function; |
5 | do { |
6 | printf ( "choose to be server(s) or client(c)?\n" ); |
7 | scanf ( "%c" ,&function); |
8 | } while (function!= 'c' && function!= 's' ); |
9 |
10 | if (function== 's' ) { |
11 | struct addrinfo hints,*localSv; |
12 | memset (&hints,0x00, sizeof (hints)); |
13 | hints.ai_family=AF_UNSPEC; |
14 | hints.ai_socktype=SOCK_STREAM; |
15 | hints.ai_flags=AI_PASSIVE; |
16 | |
17 | int rv; |
18 | rv=getaddrinfo(NULL,MYPORT,&hints,&localSv); |
19 | if (rv!=0) { |
20 | fprintf (stderr, "getaddinfo: %s\n" ,gai_strerror(rv)); |
21 | return 1; |
22 | } |
23 |
24 | int sockLs; |
25 | struct addrinfo *p; |
26 | for ( p=localSv;p;p=p->ai_next) { |
27 | if ( (sockLs=socket(p->ai_family,p->ai_socktype,p->ai_protocol))==-1) { |
28 | perror ( "server: socket" ); |
29 | continue ; |
30 | } |
31 | |
32 | if (bind(sockLs,p->ai_addr, p->ai_addrlen)==-1) { |
33 | shutdown(sockLs,2); |
34 | perror ( "server: bind" ); |
35 | continue ; |
36 | } |
37 |
38 | break ; |
39 | } //why linked table? |
40 |
41 | if (p==NULL) { |
42 | perror ( "server: failed to bind" ); |
43 | return 2; |
44 | } |
45 |
46 | freeaddrinfo(localSv); //all done with this structure.. so bind() did nothing to struct addrinfo! only to socket(create a socket, and the int is only its number). |
47 | |
48 | if (listen(sockLs,BACKLOG)==-1) { |
49 | perror ( "listen" ); |
50 | exit (1); |
51 | } |
52 | |
53 | struct sockaddr_storage clientSockaddr; |
54 | int sockCon; |
55 | printf ( "Listening..\n" ); |
56 | socklen_t clientSockaddrSize= sizeof (clientSockaddr); |
57 | sockCon=accept(sockLs,( struct sockaddr*)&clientSockaddr,&clientSockaddrSize); |
58 | printf ( "Connected.\n" ); |
59 | shutdown(sockLs,2); |
60 | |
61 | while (1) { |
62 | char buff[1024]; |
63 | recv(sockCon,buff, sizeof (buff),0); |
64 | if ( strcmp (buff, "exit" )==0) { |
65 | printf ( "Client exited.\n" ); |
66 | break ; |
67 | } |
68 | printf ( "%s\n" ,buff); |
69 | } |
70 |
71 | shutdown(sockCon,2); |
72 | } |
73 |
74 | if (function== 'c' ) { |
75 | printf ( "Sever IP:\n" ); |
76 | char svIp[16]; |
77 | scanf ( "%s" ,svIp); |
78 | |
79 | struct addrinfo hints,*remoteSv; |
80 | memset (&hints,0x00, sizeof (hints)); |
81 | hints.ai_family=AF_UNSPEC; |
82 | hints.ai_socktype=SOCK_STREAM; |
83 | int rv=getaddrinfo(svIp,MYPORT,&hints,&remoteSv); |
84 | if (rv!=0) { |
85 | fprintf (stderr, "getaddinfo: %s\n" ,gai_strerror(rv)); |
86 | return 1; |
87 | } |
88 | |
89 | int sockCl; |
90 | struct addrinfo *p; |
91 | for (p=remoteSv;p;p=p->ai_next) { |
92 | if ( (sockCl=socket(p->ai_family,p->ai_socktype,p->ai_protocol))==-1) { |
93 | perror ( "server: socket" ); |
94 | continue ; |
95 | } |
96 | |
97 | if (connect(sockCl,p->ai_addr,p->ai_addrlen)==-1) { |
98 | shutdown(sockCl,2); |
99 | printf ( "server: connect" ); |
100 | continue ; |
101 | } |
102 |
103 | break ; |
104 | } |
105 |
106 | if (p==NULL) { |
107 | perror ( "server:failed to setup" ); |
108 | return 2; |
109 | } |
110 |
111 | freeaddrinfo(remoteSv); |
112 | |
113 | printf ( "connected.\n" ); |
114 |
115 | while (1) { |
116 | char buff[1024]; |
117 | scanf ( "%s" ,buff); |
118 | send(sockCl,buff, sizeof (buff),0); |
119 | if ( strcmp (buff, "exit" )==0) { |
120 | printf ( "Exited.\n" ); |
121 | break ; |
122 | } |
123 | } |
124 | shutdown(sockCl,2); |
125 | } |
126 |
127 | return 0; |
128 | } |
用Datagram的:
1 | #include "commonheader.h" |
2 |
3 | int main() { |
4 | char function; |
5 | do { |
6 | printf ( "choose to be server(s) or client(c)?\n" ); |
7 | scanf ( "%c" ,&function); |
8 | } while (function!= 'c' && function!= 's' ); |
9 |
10 | if (function== 's' ) { |
11 | struct addrinfo hints,*localSv; |
12 | memset (&hints,0x00, sizeof (hints)); |
13 | hints.ai_family=AF_UNSPEC; |
14 | hints.ai_socktype=SOCK_DGRAM; |
15 | hints.ai_flags=AI_PASSIVE; |
16 | |
17 | int rv; |
18 | rv=getaddrinfo(NULL,MYPORT,&hints,&localSv); |
19 | if (rv!=0) { |
20 | fprintf (stderr, "getaddinfo: %s\n" ,gai_strerror(rv)); |
21 | return 1; |
22 | } |
23 |
24 | int sockLs; |
25 | struct addrinfo *p; |
26 | for ( p=localSv;p;p=p->ai_next) { |
27 | if ( (sockLs=socket(p->ai_family,p->ai_socktype,p->ai_protocol))==-1) { |
28 | perror ( "server: socket" ); |
29 | continue ; |
30 | } |
31 |
32 | if (bind(sockLs,p->ai_addr,p->ai_addrlen)==-1) { |
33 | shutdown(sockLs,2); |
34 | perror ( "server: bind" ); |
35 | } |
36 | |
37 | break ; |
38 | } //why linked table? |
39 |
40 | if (p==NULL) { |
41 | perror ( "server: failed to setup" ); |
42 | return 2; |
43 | } |
44 |
45 | freeaddrinfo(localSv); //all done with this structure.. so bind() did nothing to struct addrinfo! only to socket(create a socket, and the int is only its number). |
46 |
47 | /* |
48 | if (listen(sockLs,BACKLOG)==-1) { |
49 | perror("listen"); |
50 | exit(1); |
51 | } |
52 | |
53 | struct sockaddr_storage clientSockaddr; |
54 | int sockCon; |
55 | printf("Listening..\n"); |
56 | socklen_t clientSockaddrSize=sizeof(clientSockaddr); |
57 | sockCon=accept(sockLs,(struct sockaddr*)&clientSockaddr,&clientSockaddrSize); |
58 | printf("Connected.\n"); |
59 | shutdown(sockLs,2); |
60 | */ |
61 | |
62 | while (1) { |
63 | char buff[1024]; |
64 | struct sockaddr from; |
65 | socklen_t fromlen; |
66 | recvfrom(sockLs,buff, sizeof (buff),0, |
67 | &from,&fromlen); |
68 | if ( strcmp (buff, "exit" )==0) { |
69 | printf ( "Client exited.\n" ); |
70 | break ; |
71 | } |
72 | printf ( "%s\n" ,buff); |
73 | } |
74 |
75 | // shutdown(sockCon,2); |
76 | } |
77 |
78 | if (function== 'c' ) { |
79 | printf ( "Sever IP:\n" ); |
80 | char svIp[100]; |
81 | scanf ( "%s" ,svIp); |
82 | |
83 | struct addrinfo hints,*remoteSv; |
84 | memset (&hints,0x00, sizeof (hints)); |
85 | hints.ai_family=AF_UNSPEC; |
86 | hints.ai_socktype=SOCK_DGRAM; |
87 | int rv=getaddrinfo(svIp,MYPORT,&hints,&remoteSv); |
88 | if (rv!=0) { |
89 | fprintf (stderr, "getaddinfo: %s\n" ,gai_strerror(rv)); |
90 | return 1; |
91 | } |
92 | |
93 | int sockCl; |
94 | struct addrinfo *p; |
95 | for (p=remoteSv;p;p=p->ai_next) { |
96 | if ( (sockCl=socket(p->ai_family,p->ai_socktype,p->ai_protocol))==-1) { |
97 | perror ( "server: socket" ); |
98 | continue ; |
99 | } |
100 | |
101 | /* |
102 | if(connect(sockCl,p->ai_addr,p->ai_addrlen)==-1) { |
103 | shutdown(sockCl,2); |
104 | printf("server: connect"); |
105 | continue; |
106 | } |
107 | */ |
108 |
109 | break ; |
110 | } |
111 |
112 | if (p==NULL) { |
113 | perror ( "server:failed to setup" ); |
114 | return 2; |
115 | } |
116 |
117 | // freeaddrinfo(remoteSv); |
118 | |
119 | // printf("connected.\n"); |
120 |
121 | while (1) { |
122 | char buff[1024]; |
123 | scanf ( "%s" ,buff); |
124 | sendto(sockCl,buff, sizeof (buff),0, |
125 | p->ai_addr,p->ai_addrlen); |
126 | if ( strcmp (buff, "exit" )==0) { |
127 | printf ( "Exited.\n" ); |
128 | break ; |
129 | } |
130 | } |
131 | shutdown(sockCl,2); |
132 | } |
133 |
134 | return 0; |
135 | } |