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;
}