http://www.cppblog.com/cuijixin/archive/2008/03/14/44480.html
是不是还对用c怎么实现网络编程感到神秘莫测阿,我们这里就要撕开它神秘的面纱,呵呵。
一起来:
诶,不要着急,我们先来介绍一些网络程序的主要执行过程,主要是便于大家更好的理解下面的程序实例哦 :
1)系统启动服务器执行。服务器完成一些初始化操作,然后进入睡眠状态,等待客户机请求。
2)在网络的某台机器上,用户执行客户机程序
3)客户机进行与服务器进程建立一条连接
4)连接建立后,客户机通过网路向服务器发出请求,请求某种服务。
5)服务器接收到客户机的请求后,根据客户机请求的内容进行相应的处理,然后将处理结果返回。
6)服务器断开与客户机的连接,继续睡眠,等待其他客户机的请求。
现在介绍一个实例
功能:实现简单的服务器-客户机编程,客户机发送连接请求后接受到连接成功信息。
代码包括两部分,服务器部分(service.c)和客户机部分(client.c)
1 /*service.c*/ 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <errno.h> 5 #include <string.h> 6 #include <sys/types.h> 7 #include <netinet/in.h> 8 #include <sys/socket.h> 9 #include <sys/wait.h> 10 #define MYPORT 3490 /*开放的端口号*/ 11 #define BACKLOG 5 /*指定套接字可以接受的最大未接受客户机请求的数目*/ 12 main() 13 { 14 int sockfd,new_fd; 15 struct sockaddr_in srvaddr; 16 struct sockaddr_in cliaddr; 17 int sin_size; 18 /*创建套接字描述符*/ 19 if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) 20 { 21 perror("socket error"); 22 exit(1); 23 } 24 bzero(&srvaddr,sizeof(srvaddr)); 25 /*用自己的ip地址和端口信息填充一个internet套接字地址结构*/ 26 srvaddr.sin_family=AF_INET; 27 srvaddr.sin_port=htons(MYPORT); 28 /*函数bind将服务器的地址和套接字帮定在一起*/ 29 if(bind(sockfd,(struct sockaddr *)&srvaddr,sizeof(struct sockaddr))==-1) 30 { 31 perror("bind error"); 32 exit(1); 33 } 34 /*listen函数告诉内核,这个套接字可以接受来自客户机的请求*/ 35 if(listen(sockfd,BACKLOG)==-1) 36 { 37 perror("listen error"); 38 exit(1); 39 } 40 /*处理客户机的请求,调用函数accept来获得一个客户机的连接*/ 41 for(;;) 42 { 43 sin_size=sizeof(struct sockaddr_in); 44 if((new_fd=accept(sockfd,(struct sockaddr *)&cliaddr,&sin_size))==-1) 45 { 46 perror("accept error"); 47 continue; 48 } 49 printf("server: got connection from %s \n",inet_ntoa(cliaddr.sin_addr)); 50 /*向客户起写数据*/ 51 if(write(new_fd,"Hello,Network!\n",14)==-1) 52 perror("write error!"); 53 close(new_fd); 54 } 55 close(sockfd); 56 }
下面为client:
1 /*client.c*/ 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <errno.h> 5 #include <string.h> 6 #include <netdb.h> 7 #include <sys/types.h> 8 #include <netinet/in.h> 9 #include <sys/socket.h> 10 #define PORT 3490 11 #define MAXDATASIZE 5000 12 int main(int argc,char **argv) 13 { 14 int sockfd,nbytes; 15 char buf[1024]; 16 struct hostent *he; 17 struct sockaddr_in srvaddr; 18 if(argc!=2) 19 { 20 perror("Usage:client hostname\n"); 21 exit(1); 22 } 23 /*函数gethostbyname获得指定域名地址所对应的ip地址*/ 24 if((he=gethostbyname(argv[1]))==NULL) 25 { 26 perror("gethostbyname"); 27 exit(1); 28 } 29 /*创建套接字,返回套接字描述符*/ 30 if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) 31 { 32 perror("create socket error"); 33 exit(1); 34 } 35 bzero(&srvaddr,sizeof(srvaddr)); 36 /*用获得的远程服务器进程的ip地址和端口号来填充一个internet套接字地址结构*/ 37 srvaddr.sin_family=AF_INET; 38 srvaddr.sin_port=htons(PORT); 39 srvaddr.sin_addr=*((struct in_addr *)he->h_addr); 40 /*用connect于这个远程服务器建立一个internet连接*/ 41 if(connect(sockfd,(struct sockaddr *)&srvaddr,sizeof(struct sockaddr))==-1) 42 { 43 perror("connect error"); 44 exit(1); 45 } 46 /*调用read函数读取服务器write过来的信息*/ 47 if((nbytes=read(sockfd,buf,MAXDATASIZE))==-1) 48 { 49 perror("read error"); 50 exit(1); 51 } 52 buf[nbytes]=‘\0‘; 53 printf("read: %s",buf); 54 close(sockfd); 55 }
下面我们来编译执行看看效果哦
编译:
#gcc -o service service.c
#gcc -o client client.c
修改执行权限
#chmod 770 service
#chmod 770 client
执行
现执行服务器端哦
#./service
另开一个命令行窗口,连接服务器的3490端口
#./client localhost
呵呵,看到效果了吧
服务器端:
|
客户端
|
时间: 2024-10-10 07:56:39