Linux是目前最流行的开源操作系统,网络功能在linux下占有核心的地位,Linux网络编程指的是socket套接字编程。本博文主要介绍socket套接字API的使用及一般客户/服务器模型的编程,并用C语言具体代码实现。
实现简单的功能如下:
1、服务器端显示客户端的IP地址和端口,接收客户端发送过来的信息,并原样发送给该客户端。
2、客户端从标准输入中读取数据,发送给服务器端,然后从服务器端读取发送过来的数据并显示在屏幕上。
一、服务器端源代码
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <stdio.h> #include <string.h> #define MAX_BUFFER_LENGTH 4096 #define LISTENQ 5 #define PORT 8000 int main(void) { int serv_fd, cli_fd; socklen_t serv_len, cli_len; struct sockaddr_in serv_addr, cli_addr; char buf[MAX_BUFFER_LENGTH]; if((serv_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf("socket error\n"); return 1; } serv_len = sizeof(serv_addr); memset(&serv_addr, 0, serv_len); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(PORT); if((bind(serv_fd, (struct sockaddr *)&serv_addr, serv_len)) < 0) { printf("bind error\n"); return 1; } if((listen(serv_fd, LISTENQ)) < 0) { printf("listen error\n"); return 1; } for(;;) { cli_len = sizeof(cli_addr); if((cli_fd = accept(serv_fd, (struct sockaddr *)&cli_addr, &cli_len)) < 0) { printf("accept error\n"); return 1; } printf("client:\t%s : %d\n", inet_ntop(AF_INET, &cli_addr.sin_addr, buf, MAX_BUFFER_LENGTH), ntohs(cli_addr.sin_port)); int nbytes; while((nbytes = read(cli_fd, buf, MAX_BUFFER_LENGTH)) > 0) { buf[nbytes] = '\0'; printf("%s", buf); if(write(cli_fd, buf, nbytes) != nbytes) { printf("write error\n"); return 1; } } if(nbytes < 0) { printf("read error\n"); return 1; } close(cli_fd); } return 0; }
二、客户端源代码
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <stdio.h> #include <string.h> #define MAX_BUFFER_LENGTH 4096 #define PORT 8000 int main(void) { int sockfd, nbytes; struct sockaddr_in serv_addr; char buf[MAX_BUFFER_LENGTH + 1]; char *host_ip = "127.0.0.1"; if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf("socket error\n"); return 1; } memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; if(inet_pton(AF_INET, host_ip, &serv_addr.sin_addr) <= 0) { printf("inet_pton error\n"); return 1; } serv_addr.sin_port = htons(PORT); if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { printf("connect error\n"); return 1; } while(fgets(buf, MAX_BUFFER_LENGTH, stdin) != NULL) { if(write(sockfd, buf, strlen(buf)) != strlen(buf)) { printf("write error\n"); return 1; } if((nbytes = read(sockfd, buf, MAX_BUFFER_LENGTH)) > 0) { buf[nbytes] = '\0'; printf("%s", buf); } if(nbytes < 0) { printf("read error\n"); return 1; } } close(sockfd); return 0; }
三、运行结果
[root@localhost workspace]# ./simple_tcp_server client: 127.0.0.1 : 58013 hello world www.xieyincai.com beijing shanghai client: 127.0.0.1 : 58089 C LANGUAGE linux
[root@localhost workspace]# ./simple_tcp_client hello world hello world www.xieyincai.com www.xieyincai.com beijing beijing shanghai shanghai [root@localhost workspace]# ./simple_tcp_client C LANGUAGE C LANGUAGE linux linux [root@localhost workspace]#