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有点小不一样, 我不知道 :):
头文件..
#include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <arpa/inet.h> #include <stdlib.h> #define MYPORT "2222" #define BACKLOG 10
用Stream的:
(两个楞大的大括号…)
#include "commonheader.h" int main() { char function; do { printf("choose to be server(s) or client(c)?\n"); scanf("%c",&function); } while(function!='c' && function!='s'); if(function=='s') { struct addrinfo hints,*localSv; memset(&hints,0x00,sizeof(hints)); hints.ai_family=AF_UNSPEC; hints.ai_socktype=SOCK_STREAM; hints.ai_flags=AI_PASSIVE; int rv; rv=getaddrinfo(NULL,MYPORT,&hints,&localSv); if(rv!=0) { fprintf(stderr,"getaddinfo: %s\n",gai_strerror(rv)); return 1; } int sockLs; struct addrinfo *p; for( p=localSv;p;p=p->ai_next) { if( (sockLs=socket(p->ai_family,p->ai_socktype,p->ai_protocol))==-1) { perror("server: socket"); continue; } if(bind(sockLs,p->ai_addr, p->ai_addrlen)==-1) { shutdown(sockLs,2); perror("server: bind"); continue; } break; }//why linked table? if(p==NULL) { perror("server: failed to bind"); return 2; } 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). if (listen(sockLs,BACKLOG)==-1) { perror("listen"); exit(1); } struct sockaddr_storage clientSockaddr; int sockCon; printf("Listening..\n"); socklen_t clientSockaddrSize=sizeof(clientSockaddr); sockCon=accept(sockLs,(struct sockaddr*)&clientSockaddr,&clientSockaddrSize); printf("Connected.\n"); shutdown(sockLs,2); while(1) { char buff[1024]; recv(sockCon,buff,sizeof(buff),0); if(strcmp(buff,"exit")==0) { printf("Client exited.\n"); break; } printf("%s\n",buff); } shutdown(sockCon,2); } if(function=='c') { printf("Sever IP:\n"); char svIp[16]; scanf("%s",svIp); struct addrinfo hints,*remoteSv; memset(&hints,0x00,sizeof(hints)); hints.ai_family=AF_UNSPEC; hints.ai_socktype=SOCK_STREAM; int rv=getaddrinfo(svIp,MYPORT,&hints,&remoteSv); if(rv!=0) { fprintf(stderr,"getaddinfo: %s\n",gai_strerror(rv)); return 1; } int sockCl; struct addrinfo *p; for(p=remoteSv;p;p=p->ai_next) { if( (sockCl=socket(p->ai_family,p->ai_socktype,p->ai_protocol))==-1) { perror("server: socket"); continue; } if(connect(sockCl,p->ai_addr,p->ai_addrlen)==-1) { shutdown(sockCl,2); printf("server: connect"); continue; } break; } if(p==NULL) { perror("server:failed to setup"); return 2; } freeaddrinfo(remoteSv); printf("connected.\n"); while(1) { char buff[1024]; scanf("%s",buff); send(sockCl,buff,sizeof(buff),0); if(strcmp(buff,"exit")==0) { printf("Exited.\n"); break; } } shutdown(sockCl,2); } return 0; }
用Datagram的:
#include "commonheader.h" int main() { char function; do { printf("choose to be server(s) or client(c)?\n"); scanf("%c",&function); } while(function!='c' && function!='s'); if(function=='s') { struct addrinfo hints,*localSv; memset(&hints,0x00,sizeof(hints)); hints.ai_family=AF_UNSPEC; hints.ai_socktype=SOCK_DGRAM; hints.ai_flags=AI_PASSIVE; int rv; rv=getaddrinfo(NULL,MYPORT,&hints,&localSv); if(rv!=0) { fprintf(stderr,"getaddinfo: %s\n",gai_strerror(rv)); return 1; } int sockLs; struct addrinfo *p; for( p=localSv;p;p=p->ai_next) { if( (sockLs=socket(p->ai_family,p->ai_socktype,p->ai_protocol))==-1) { perror("server: socket"); continue; } if(bind(sockLs,p->ai_addr,p->ai_addrlen)==-1) { shutdown(sockLs,2); perror("server: bind"); } break; }//why linked table? if(p==NULL) { perror("server: failed to setup"); return 2; } 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). /* if (listen(sockLs,BACKLOG)==-1) { perror("listen"); exit(1); } struct sockaddr_storage clientSockaddr; int sockCon; printf("Listening..\n"); socklen_t clientSockaddrSize=sizeof(clientSockaddr); sockCon=accept(sockLs,(struct sockaddr*)&clientSockaddr,&clientSockaddrSize); printf("Connected.\n"); shutdown(sockLs,2); */ while(1) { char buff[1024]; struct sockaddr from; socklen_t fromlen; recvfrom(sockLs,buff,sizeof(buff),0, &from,&fromlen); if(strcmp(buff,"exit")==0) { printf("Client exited.\n"); break; } printf("%s\n",buff); } // shutdown(sockCon,2); } if(function=='c') { printf("Sever IP:\n"); char svIp[100]; scanf("%s",svIp); struct addrinfo hints,*remoteSv; memset(&hints,0x00,sizeof(hints)); hints.ai_family=AF_UNSPEC; hints.ai_socktype=SOCK_DGRAM; int rv=getaddrinfo(svIp,MYPORT,&hints,&remoteSv); if(rv!=0) { fprintf(stderr,"getaddinfo: %s\n",gai_strerror(rv)); return 1; } int sockCl; struct addrinfo *p; for(p=remoteSv;p;p=p->ai_next) { if( (sockCl=socket(p->ai_family,p->ai_socktype,p->ai_protocol))==-1) { perror("server: socket"); continue; } /* if(connect(sockCl,p->ai_addr,p->ai_addrlen)==-1) { shutdown(sockCl,2); printf("server: connect"); continue; } */ break; } if(p==NULL) { perror("server:failed to setup"); return 2; } // freeaddrinfo(remoteSv); // printf("connected.\n"); while(1) { char buff[1024]; scanf("%s",buff); sendto(sockCl,buff,sizeof(buff),0, p->ai_addr,p->ai_addrlen); if(strcmp(buff,"exit")==0) { printf("Exited.\n"); break; } } shutdown(sockCl,2); } return 0; }