7. Socket编程实例
服务器端:一直监听本机的8000号端口,如果收到连接请求,将接收请求并接收客户端发来的消息,并向客户端返回消息。
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<errno.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #define DEFAULT_PORT 8000 #define MAXLINE 4096 int main( int argc, char ** argv) { int socket_fd, connect_fd; struct sockaddr_in servaddr; char buff[4096]; int n; if ( (socket_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){ printf("create socket error: %s(errno: %d)\n" ,strerror(errno),errno); exit(0); } memset(&servaddr, 0, sizeof (servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(DEFAULT_PORT); if ( bind(socket_fd, ( struct sockaddr*)&servaddr, sizeof (servaddr)) == -1){ printf("bind socket error: %s(errno: %d)\n" ,strerror(errno),errno); exit(0); } if ( listen(socket_fd, 10) == -1){ printf("listen socket error: %s(errno: %d)\n" ,strerror(errno),errno); exit(0); } printf("======waiting for client's request======\n" ); while (1){ if ( (connect_fd = accept(socket_fd, ( struct sockaddr*)NULL, NULL)) == -1){ printf("accept socket error: %s(errno: %d)" ,strerror(errno),errno); continue ; } n = recv(connect_fd, buff, MAXLINE, 0); if (!fork()){ if (send(connect_fd, "Hello,you are connected!\n" , 26,0) == -1) perror("send error" ); close(connect_fd); exit(0); } buff[n] = '\0' ; printf("recv msg from client: %s\n" , buff); close(connect_fd); } close(socket_fd); }
客户端:
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<errno.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #define MAXLINE 4096 int main( int argc, char ** argv) { int sockfd, n,rec_len; char recvline[4096], sendline[4096]; char buf[MAXLINE]; struct sockaddr_in servaddr; if ( argc != 2){ printf("usage: ./client <ipaddress>\n" ); exit(0); } if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){ printf("create socket error: %s(errno: %d)\n" , strerror(errno),errno); exit(0); } memset(&servaddr, 0, sizeof (servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(8000); if ( inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0){ printf("inet_pton error for %s\n" ,argv[1]); exit(0); } if ( connect(sockfd, ( struct sockaddr*)&servaddr, sizeof (servaddr)) < 0){ printf("connect error: %s(errno: %d)\n" ,strerror(errno),errno); exit(0); } printf("send msg to server: \n" ); fgets(sendline, 4096, stdin); if ( send(sockfd, sendline, strlen(sendline), 0) < 0) { printf("send msg error: %s(errno: %d)\n" , strerror(errno), errno); exit(0); } if ((rec_len = recv(sockfd, buf, MAXLINE,0)) == -1) { perror("recv error" ); exit(1); } buf[rec_len] = '\0' ; printf("Received : %s " ,buf); close(sockfd); exit(0); }
inet_pton 是Linux下IP地址转换函数,可以在将IP地址在“点分十进制”和“整数”之间转换 ,是inet_addr的扩展。
int inet_pton( int af, const char *src, void *dst);
第一个参数af是地址族,转换后存在dst中
af = AF_INET:src为指向字符型的地址,即ASCII的地址的首地址(ddd.ddd.ddd.ddd格式的),函数将该地址转换为in_addr的结构体,并复制在*dst中
af =AF_INET6:src为指向IPV6的地址,函数将该地址转换为in6_addr的结构体,并复制在*dst中
如果函数出错将返回一个负值,并将errno设置为EAFNOSUPPORT,如果参数af指定的地址族和src格式不对,函数将返回0。
测试 :
编译server.c
gcc -o server server.c
启动进程:
./server
显示结果:
======waiting for client's request======
并等待客户端连接。
编译 client.c
gcc -o client server.c
客户端去连接server:
./client 127.0.0.1
等待输入消息