linux下socket通信,server和client简单例子(一)

本文介绍了一个简单的TCP服务器实现,该服务器能够接收客户端发送的文件名请求,并将指定的文件内容发送回客户端。服务器通过监听特定端口,接受客户端连接,读取文件并逐块发送。

1. [代码]c代码 server部分     

001 server.c
002  
003 ====================================================================
004  
005 #include <netinet/in.h>    // for sockaddr_in
006 #include <sys/types.h>    // for socket
007 #include <sys/socket.h>    // for socket
008 #include <stdio.h>        // for printf
009 #include <stdlib.h>        // for exit
010 #include <string.h>        // for bzero
011 /*
012 #include <sys/types.h>
013 #include <sys/stat.h>
014 #include <fcntl.h>
015 #include <unistd.h>
016 */
017 #define HELLO_WORLD_SERVER_PORT    6666
018 #define LENGTH_OF_LISTEN_QUEUE 20
019 #define BUFFER_SIZE 1024
020 #define FILE_NAME_MAX_SIZE 512
021  
022 int main(int argc, char **argv)
023 {
024     //设置一个socket地址结构server_addr,代表服务器internet地址, 端口
025     struct sockaddr_in server_addr;
026     bzero(&server_addr,sizeof(server_addr)); //把一段内存区的内容全部设置为0
027     server_addr.sin_family = AF_INET;
028     server_addr.sin_addr.s_addr = htons(INADDR_ANY);
029     server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
030  
031     //创建用于internet的流协议(TCP)socket,用server_socket代表服务器socket
032     int server_socket = socket(PF_INET,SOCK_STREAM,0);
033     if( server_socket < 0)
034     {
035         printf("Create Socket Failed!");
036         exit(1);
037     }
038 {
039    int opt =1;
040    setsockopt(server_socket,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
041 }
042      
043     //把socket和socket地址结构联系起来
044     if( bind(server_socket,(struct sockaddr*)&server_addr,sizeof(server_addr)))
045     {
046         printf("Server Bind Port : %d Failed!", HELLO_WORLD_SERVER_PORT);
047         exit(1);
048     }
049  
050     //server_socket用于监听
051     if ( listen(server_socket, LENGTH_OF_LISTEN_QUEUE) )
052     {
053         printf("Server Listen Failed!");
054         exit(1);
055     }
056     while (1) //服务器端要一直运行
057     {
058         //定义客户端的socket地址结构client_addr
059         struct sockaddr_in client_addr;
060         socklen_t length = sizeof(client_addr);
061  
062         //接受一个到server_socket代表的socket的一个连接
063         //如果没有连接请求,就等待到有连接请求--这是accept函数的特性
064         //accept函数返回一个新的socket,这个socket(new_server_socket)用于同连接到的客户的通信
065         //new_server_socket代表了服务器和客户端之间的一个通信通道
066         //accept函数把连接到的客户端信息填写到客户端的socket地址结构client_addr中
067         int new_server_socket = accept(server_socket,(structsockaddr*)&client_addr,&length);
068         if ( new_server_socket < 0)
069         {
070             printf("Server Accept Failed!\n");
071             break;
072         }
073          
074         char buffer[BUFFER_SIZE];
075         bzero(buffer, BUFFER_SIZE);
076         length = recv(new_server_socket,buffer,BUFFER_SIZE,0);
077         if (length < 0)
078         {
079             printf("Server Recieve Data Failed!\n");
080             break;
081         }
082         char file_name[FILE_NAME_MAX_SIZE+1];
083         bzero(file_name, FILE_NAME_MAX_SIZE+1);
084         strncpy(file_name, buffer, strlen(buffer)>FILE_NAME_MAX_SIZE?FILE_NAME_MAX_SIZE:strlen(buffer));
085 //        int fp = open(file_name, O_RDONLY);
086 //        if( fp < 0 )
087         printf("%s\n",file_name);
088         FILE * fp = fopen(file_name,"r");
089         if(NULL == fp )
090         {
091             printf("File:\t%s Not Found\n", file_name);
092         }
093         else
094         {
095             bzero(buffer, BUFFER_SIZE);
096             int file_block_length = 0;
097 //            while( (file_block_length = read(fp,buffer,BUFFER_SIZE))>0)
098             while( (file_block_length = fread(buffer,sizeof(char),BUFFER_SIZE,fp))>0)
099             {
100                 printf("file_block_length = %d\n",file_block_length);
101                 //发送buffer中的字符串到new_server_socket,实际是给客户端
102                 if(send(new_server_socket,buffer,file_block_length,0)<0)
103                 {
104                     printf("Send File:\t%s Failed\n", file_name);
105                     break;
106                 }
107                 bzero(buffer, BUFFER_SIZE);
108             }
109 //            close(fp);
110             fclose(fp);
111             printf("File:\t%s Transfer Finished\n",file_name);
112         }
113         //关闭与客户端的连接
114         close(new_server_socket);
115     }
116     //关闭监听用的socket
117     close(server_socket);
118     return 0;
119 }

   
### ### TCP 服务器端示例代码 以下是个在 Linux 环境下使用 C++ 实现的基于 TCP 协议的简单 Socket 服务器端通信代码。该代码使用 `socket`、`bind`、`listen` `accept` 函数完成基本的连接建立,并通过 `send` `recv` 进行数据收发[^2]。 ```cpp #include <iostream> #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <cstring> int main() { int server_fd, new_socket; struct sockaddr_in address; int addrlen = sizeof(address); char buffer[1024] = {0}; const char* response = "Message received"; // 创建套接字 server_fd = socket(AF_INET, SOCK_STREAM, 0); if (server_fd < 0) { std::cerr << "Socket creation error" << std::endl; return -1; } // 设置地址端口 address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(8080); // 绑定套接字到地址端口 if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { std::cerr << "Bind failed" << std::endl; close(server_fd); return -1; } // 监听连接 if (listen(server_fd, 3) < 0) { std::cerr << "Listen failed" << std::endl; close(server_fd); return -1; } std::cout << "Server is listening on port 8080..." << std::endl; // 接受客户端连接 new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen); if (new_socket < 0) { std::cerr << "Accept failed" << std::endl; close(server_fd); return -1; } // 接收客户端消息 int valread = recv(new_socket, buffer, 1024, 0); if (valread > 0) { std::cout << "Received: " << buffer << std::endl; // 发送响应 send(new_socket, response, strlen(response), 0); std::cout << "Response sent" << std::endl; } // 关闭连接 close(new_socket); close(server_fd); return 0; } ``` ### ### TCP 客户端示例代码 以下为对应的客户端代码,使用 `socket` `connect` 建立连接,并通过 `send` 向服务器发送消息,再用 `recv` 接收响应[^3]。 ```cpp #include <iostream> #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <cstring> int main() { int sock = 0; struct sockaddr_in serv_addr; const char* message = "Hello from client"; char buffer[1024] = {0}; // 创建套接字 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { std::cerr << "Socket creation error" << std::endl; return -1; } serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(8080); // 将 IP 地址从字符串转换为二进制形式 if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) { std::cerr << "Invalid address / Address not supported" << std::endl; return -1; } // 连接服务器 if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { std::cerr << "Connection Failed" << std::endl; return -1; } // 发送消息给服务器 send(sock, message, strlen(message), 0); std::cout << "Message sent to server" << std::endl; // 接收服务器响应 int valread = recv(sock, buffer, 1024, 0); if (valread > 0) { std::cout << "Server response: " << buffer << std::endl; } // 关闭连接 close(sock); return 0; } ``` ### ### 编译与运行 使用 g++ 编译上述代码: ```bash g++ server.cpp -o server g++ client.cpp -o client ``` 运行顺序如下: 1. 先运行服务器端程序: ```bash ./server ``` 2. 再打开另个终端运行客户端程序: ```bash ./client ``` 客户端将向服务器发送条文本消息,服务器接收后会打印并回传确认信息。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值