Linux网络编程之Helloworld实例
2012-11-02 16:27 Chung-shu 阅读(408) 评论(0) 收藏 举报1. 服务端程序(server.c)
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/wait.h> #include <memory.h> /*能够同时接受的连接数*/ #define BACKLOG 10 int main(int argc, char *argv[]) { int sockfd, new_fd; struct sockaddr_in server_addr; struct sockaddr_in client_addr; int sin_size, portnumber; char hello[]="Hello! Are you OK?\n"; if(argc!=2) { printf("portnumber error!\n"); exit(1); } if((portnumber=atoi(argv[1]))<0) { printf("portnumber error!\n"); exit(1); } /*服务器端建立socket描述符*/ if((sockfd=socket(AF_INET, SOCK_STREAM, 0))==-1) { printf("socket error: %s.\n", strerror(errno)); exit(1); } /*服务器端填充sockaddr结构*/ //bzero(&server_addr, sizeof(struct sockaddr_in)); memset(&server_addr, 0, sizeof(struct sockaddr_in)); server_addr.sin_family=AF_INET; server_addr.sin_addr.s_addr=htonl(INADDR_ANY); server_addr.sin_port=htons(portnumber); /*捆绑sockfd描述符*/ if(bind(sockfd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr))==-1) { printf("bind error: %s.\n", strerror(errno)); exit(1); } /*监听sockfd描述符*/ if(listen(sockfd, BACKLOG)==-1) { printf("listen error: %s.\n", strerror(errno)); exit(1); } while(1) { /*服务器阻塞,直到客户程序建立连接*/ sin_size=sizeof(struct sockaddr_in); if((new_fd=accept(sockfd, (struct sockaddr *)(&client_addr), &sin_size))==-1) { printf("accept error: %s.\n", strerror(errno)); continue; } printf("server get connection from %s\n", inet_ntoa(client_addr.sin_addr)); if(write(new_fd, hello, strlen(hello))==-1) { printf("write error: %s.\n", strerror(errno)); exit(1); } close(new_fd); } close(sockfd); return 0; }
2. 客户端程序(client.c)
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <netdb.h> #include <netinet/in.h> #include <sys/socket.h> #include <memory.h> int main(int argc, char *argv[]) { int sockfd; char buffer[1024]; struct sockaddr_in server_addr; unsigned long s_addr; int portnumber, nbytes; if(argc!=3) { printf("ip address or portnumber error.\n"); exit(1); } if((s_addr=inet_addr(argv[1]))==-1) { printf("ip address or portnumber error.\n"); exit(1); } if((portnumber=atoi(argv[2]))<0) { printf("ip address or portnumber error.\n"); exit(1); } /*客户程序开始建立sockfd描述符*/ if((sockfd=socket(AF_INET, SOCK_STREAM, 0))==-1) { printf("socket error: %s.\n", strerror(errno)); exit(1); } /*客户程序填充服务端信息*/ //bzero(&server_addr, sizeof(server_addr)); memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family=AF_INET; server_addr.sin_port=htons(portnumber); /*server_addr.sin_addr=*((struct in_addr *)host->h_addr);*/ server_addr.sin_addr.s_addr=s_addr; /*客户端程序发起连接请求*/ if(connect(sockfd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr))==-1) { printf("connect error: %s.\n", strerror(errno)); exit(1); } /*连接成功*/ if((nbytes=read(sockfd, buffer, 1024))==-1) { printf("read error: %s.\n", strerror(errno)); exit(1); } buffer[nbytes]='\0'; printf("I have received: %s\n", buffer); /*结束通信*/ close(sockfd); return 0; }
3. 由于目标文件需要运行在mips-linux平台下,需要编写Makefile文件
CC=mips-linux-gcc CFLAGS=-O2 -static LDFLAGS=-Wl,--trace,--print-map,--cref all:server client server:server.o $(CC) $(LDFLAGS) -o server server.o server.o:server.c $(CC) -c $(CFLAGS) server.c client:client.o $(CC) $(LDFLAGS) -o client client.o client.o:client.c $(CC) -c $(CFLAGS) client.c clean: rm -f *.o
4. make
将目标文件下载到设备中即可运行。
5. 以上服务器端采用的是循环方式,如果该进程阻塞,则不能响应其他客户端的请求,改为并发方式可以解决这个问题,代码如下:
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/wait.h> #include <memory.h> /*能够同时接受的连接数*/ #define BACKLOG 10 int main(int argc, char *argv[]) { int sockfd, new_fd; struct sockaddr_in server_addr; struct sockaddr_in client_addr; int n, sin_size, portnumber, child_process; if(argc!=2) { printf("portnumber error!\n"); exit(1); } if((portnumber=atoi(argv[1]))<0) { printf("portnumber error!\n"); exit(1); } /*服务器端建立socket描述符*/ if((sockfd=socket(AF_INET, SOCK_STREAM, 0))==-1) { printf("socket error: %s.\n", strerror(errno)); exit(1); } /*服务器端填充sockaddr结构*/ bzero(&server_addr, sizeof(struct sockaddr_in)); server_addr.sin_family=AF_INET; server_addr.sin_addr.s_addr=htonl(INADDR_ANY); server_addr.sin_port=htons(portnumber); /*如果服务器终止,可以快速启动而不用等待一段时间*/ n=1; setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(int)); /*捆绑sockfd描述符*/ if(bind(sockfd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr))==-1) { printf("bind error: %s.\n", strerror(errno)); exit(1); } /*监听sockfd描述符*/ if(listen(sockfd, BACKLOG)==-1) { printf("listen error: %s.\n", strerror(errno)); exit(1); } while(1) { if((new_fd=accept(sockfd, (struct sockaddr *)(&client_addr), &sin_size))==-1) { printf("accept error: %s.\n", strerror(errno)); continue; } if((child_process=fork())==0) { char hello[30]; sprintf(hello, "Child Process %d: Hello! Are you OK?", getpid()); printf("server get connection from %s\n", inet_ntoa(client_addr.sin_addr)); if(write(new_fd, hello, strlen(hello))==-1) { printf("write error: %s.\n", strerror(errno)); } close(new_fd); exit(1); } else if(child_process==-1) printf("fork error: %s.\n", strerror(errno)); close(new_fd); } return 0; }
浙公网安备 33010602011771号