Linux下系统调用编程socket(2)
来源:互联网 发布:矩阵的秩代表什么 编辑:程序博客网 时间:2024/05/22 02:17
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
等待输入消息
0 0