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

http://www.oschina.net/code/snippet_97047_675


[1].[代码] c代码 server部分 跳至 [1] [2] [3]

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,(struct sockaddr*)&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 }

[2].[代码] c代码 client部分 跳至 [1] [2] [3]

001 client.c
002  
003 #include <netinet/in.h>    // for sockaddr_in
004 #include <sys/types.h>    // for socket
005 #include <sys/socket.h>    // for socket
006 #include <stdio.h>        // for printf
007 #include <stdlib.h>        // for exit
008 #include <string.h>        // for bzero
009 /*
010 #include <sys/types.h>
011 #include <sys/stat.h>
012 #include <fcntl.h>
013 #include <unistd.h>
014 */
015  
016 #define HELLO_WORLD_SERVER_PORT    6666
017 #define BUFFER_SIZE 1024
018 #define FILE_NAME_MAX_SIZE 512
019  
020 int main(int argc, char **argv)
021 {
022     if (argc != 2)
023     {
024         printf("Usage: ./%s ServerIPAddress\n",argv[0]);
025         exit(1);
026     }
027  
028     //设置一个socket地址结构client_addr,代表客户机internet地址, 端口
029     struct sockaddr_in client_addr;
030     bzero(&client_addr,sizeof(client_addr)); //把一段内存区的内容全部设置为0
031     client_addr.sin_family = AF_INET;    //internet协议族
032     client_addr.sin_addr.s_addr = htons(INADDR_ANY);//INADDR_ANY表示自动获取本机地址
033     client_addr.sin_port = htons(0);    //0表示让系统自动分配一个空闲端口
034     //创建用于internet的流协议(TCP)socket,用client_socket代表客户机socket
035     int client_socket = socket(AF_INET,SOCK_STREAM,0);
036     if( client_socket < 0)
037     {
038         printf("Create Socket Failed!\n");
039         exit(1);
040     }
041     //把客户机的socket和客户机的socket地址结构联系起来
042     if( bind(client_socket,(struct sockaddr*)&client_addr,sizeof(client_addr)))
043     {
044         printf("Client Bind Port Failed!\n");
045         exit(1);
046     }
047  
048     //设置一个socket地址结构server_addr,代表服务器的internet地址, 端口
049     struct sockaddr_in server_addr;
050     bzero(&server_addr,sizeof(server_addr));
051     server_addr.sin_family = AF_INET;
052     if(inet_aton(argv[1],&server_addr.sin_addr) == 0) //服务器的IP地址来自程序的参数
053     {
054         printf("Server IP Address Error!\n");
055         exit(1);
056     }
057     server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
058     socklen_t server_addr_length = sizeof(server_addr);
059     //向服务器发起连接,连接成功后client_socket代表了客户机和服务器的一个socket连接
060     if(connect(client_socket,(struct sockaddr*)&server_addr, server_addr_length) < 0)
061     {
062         printf("Can Not Connect To %s!\n",argv[1]);
063         exit(1);
064     }
065  
066     char file_name[FILE_NAME_MAX_SIZE+1];
067     bzero(file_name, FILE_NAME_MAX_SIZE+1);
068     printf("Please Input File Name On Server:\t");
069     scanf("%s", file_name);
070      
071     char buffer[BUFFER_SIZE];
072     bzero(buffer,BUFFER_SIZE);
073     strncpy(buffer, file_name, strlen(file_name)>BUFFER_SIZE?BUFFER_SIZE:strlen(file_name));
074     //向服务器发送buffer中的数据
075     send(client_socket,buffer,BUFFER_SIZE,0);
076  
077 //    int fp = open(file_name, O_WRONLY|O_CREAT);
078 //    if( fp < 0 )
079     FILE * fp = fopen(file_name,"w");
080     if(NULL == fp )
081     {
082         printf("File:\t%s Can Not Open To Write\n", file_name);
083         exit(1);
084     }
085      
086     //从服务器接收数据到buffer中
087     bzero(buffer,BUFFER_SIZE);
088     int length = 0;
089     while( length = recv(client_socket,buffer,BUFFER_SIZE,0))
090     {
091         if(length < 0)
092         {
093             printf("Recieve Data From Server %s Failed!\n", argv[1]);
094             break;
095         }
096 //        int write_length = write(fp, buffer,length);
097         int write_length = fwrite(buffer,sizeof(char),length,fp);
098         if (write_length<length)
099         {
100             printf("File:\t%s Write Failed\n", file_name);
101             break;
102         }
103         bzero(buffer,BUFFER_SIZE);   
104     }
105     printf("Recieve File:\t %s From Server[%s] Finished\n",file_name, argv[1]);
106      
107     close(fp);
108     //关闭socket
109     close(client_socket);
110     return 0;
111 }

[3].[代码] open等,fopen等说明 跳至 [1] [2] [3]

01 某些注释部分,open,read,write被 fopen,fread,fwrite替换。
02  
03 说明一下:
04 fopenfclosefreadfwritefgetcfgetsfputcfputsfreopenfseekftellrewind
05 缓冲文件系统
06 缓冲文件系统的特点是:在内存开辟一个“缓冲区”,为程序中的每一个文件使用,当执行读文件的操作时,
07 从磁盘文件将数据先读入内存“缓冲区”, 装满后再从内存“缓冲区”依此读入接收的变量。执行写文件的
08 操作时,先将数据写入内存“缓冲区”,待内存“缓冲区”装满后再写入文件。由此可以看出,内存
09 “缓冲区”的大小,影响着实际操作外存的次数,内存“缓冲区”越大,则操作外存的次数就少,
10 执行速度就快、效率高。一般来说,文件“缓冲区”的大小随机器 而定。
11  
12 open, close, read, write, getcgetcharputcputchar 
13 非缓冲文件系统
14 非缓冲文件系统是借助文件结构体指针来对文件进行管理,通过文件指针来对文件进行访问,既可以读写字符、
15 字符串、格式化数据,也可以读写二进制数 据。非缓冲文件系统依赖于操作系统,通过操作系统的功能对
16 文件进行读写,是系统级的输入输出,它不设文件结构体指针,只能读写二进制文件,但效率高、速度快,
17 由于ANSI标准不再包括非缓冲文件系统,因此建议大家最好不要选择它。
18  
19 open等属于低级IO,
20 fopen等是高级IO。
21  
22 open等返回一个文件描述符(用户程序区的),
23 fopen等返回一个文件指针。
24  
25 open等无缓冲,fopen等有缓冲。
26  
27 fopen等是在open等的基础上扩充而来的,在大多数情况下,用fopen等。
28  
29 open 是系统调用 返回的是文件句柄,文件的句柄是文件在文件描述符表里的索引,
30 fopen是C的库函数,返回的是一个指向文件结构的指针。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!对于您提到的问题,我可以为您提供一些基本的信息。 在C++,您可以使用多线程来实现并发的程序。多线程允许您同时执行多个任务,以提高程序的效率和性能。C++11引入了一个线程库,其包含了一些与多线程编程相关的类和函数。 在Linux环境下,您可以使用socket进行网络通信Socket是一种通信机制,它允许不同的计算机通过网络进行数据交换。在C++,可以使用socket API来创建、连接、发送和接收数据。 下面是一个简单的示例代码,展示了在Linux环境下使用多线程和socket进行通信的基本步骤: ```cpp #include <iostream> #include <thread> #include <sys/socket.h> #include <arpa/inet.h> void clientThread() { // 创建socket int clientSocket = socket(AF_INET, SOCK_STREAM, 0); // 设置服务器的IP地址和端口号 struct sockaddr_in serverAddress; serverAddress.sin_family = AF_INET; serverAddress.sin_port = htons(12345); serverAddress.sin_addr.s_addr = inet_addr("127.0.0.1"); // 连接到服务器 connect(clientSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress)); // 发送数据 const char* message = "Hello from client!"; send(clientSocket, message, strlen(message), 0); // 关闭socket close(clientSocket); } int main() { // 创建一个新线程来执行客户端代码 std::thread clientThread(clientThread); // 等待线程执行完毕 clientThread.join(); return 0; } ``` 这只是一个简单例子,仅用于演示多线程和socket通信的基本概念。在实际应用,您可能还需要处理错误、添加更多的功能等。 希望这些信息对您有所帮助!如果您有任何进一步的问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值