• 《TCP/IP网络编程》--基于TCP实现字符串对话和文件传输


    1--基于TCP实现字符串对话

    主要需求:

            服务器端和客户端各传递 1 次字符串,基于 TCP 协议,传递字符串前先以 4 字节整数型方式传递字符串长度,剩余部分为字符串数据;

    注:下面的代码基于 Windows 系统实现;

    1-1--服务器端

    1. // gcc string_server_win.c -o string_server_win -lwsock32
    2. // string_server_win 9190
    3. #include
    4. #include
    5. #include
    6. #include
    7. #define BUF_SIZE 1024
    8. #define Len_SIZE 4
    9. void ErrorHandling(char *message){
    10. fputs(message, stderr);
    11. fputc('\n', stderr);
    12. exit(1);
    13. }
    14. int main(int argc, char *argv[]){
    15. if (argc != 2) {
    16. printf("Usage: %s \n", argv[0]);
    17. exit(1);
    18. }
    19. WSADATA wsaData; // init Socket lib
    20. if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){
    21. ErrorHandling("WSAStartup() error!");
    22. }
    23. int Serv_sock = socket(PF_INET, SOCK_STREAM, 0); // create socket
    24. if (Serv_sock == -1) {
    25. ErrorHandling("socket() error");
    26. }
    27. struct sockaddr_in serv_addr; // allocate ip, port
    28. memset(&serv_addr, 0, sizeof(serv_addr));
    29. serv_addr.sin_family = AF_INET;
    30. serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    31. serv_addr.sin_port = htons(atoi(argv[1]));
    32. if (bind(Serv_sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1){
    33. ErrorHandling("bind() error");
    34. }
    35. if (listen(Serv_sock, 5) == -1) { // ready
    36. ErrorHandling("listen() error");
    37. }
    38. struct sockaddr_in clnt_addr;
    39. int clnt_addr_size = sizeof(clnt_addr);
    40. for (int i = 0; i < 5; ++i) {
    41. int Clnt_sock = accept(Serv_sock, (struct sockaddr*) &clnt_addr, &clnt_addr_size); // accept
    42. if (Clnt_sock == -1){
    43. ErrorHandling("accept() error");
    44. }
    45. else{
    46. printf("Connected client %d \n", i+1);
    47. }
    48. while(1) {
    49. int over = 0, recv_len = 0, msg_len, recv_cnt;
    50. char msg[BUF_SIZE];
    51. while (recv_len == 0 || recv_len < msg_len + Len_SIZE) {
    52. recv_cnt = recv(Clnt_sock, (char*)&msg[recv_len], BUF_SIZE, 0);
    53. if (recv_cnt == -1) {
    54. ErrorHandling("read() error!");
    55. }
    56. if (recv_cnt == 0) {
    57. over = 1;
    58. break;
    59. }
    60. recv_len += recv_cnt;
    61. if (recv_len >= Len_SIZE) {
    62. memcpy(&msg_len, msg, Len_SIZE);
    63. }
    64. }
    65. msg[recv_len] = '\0';
    66. if (over == 1) {
    67. break;
    68. }
    69. printf("Message from client: %s", msg + Len_SIZE); // output message from client
    70. fputs("Input message: ", stdout);
    71. fgets(msg + Len_SIZE, BUF_SIZE - Len_SIZE, stdin); // input message
    72. int len = strlen(msg + Len_SIZE);
    73. memcpy(msg, &len, Len_SIZE);
    74. send(Clnt_sock, msg, Len_SIZE + len, 0); // send message to client
    75. }
    76. closesocket(Clnt_sock);
    77. }
    78. closesocket(Serv_sock);
    79. return 0;
    80. }

    1-2--客户端

    1. // gcc string_client_win.c -o string_client_win -lwsock32
    2. // string_client_win 127.0.0.1 9190
    3. #include
    4. #include
    5. #include
    6. #include
    7. #define BUF_SIZE 1024
    8. #define Len_SIZE 4
    9. void ErrorHandling(char *message){
    10. fputs(message, stderr);
    11. fputc('\n', stderr);
    12. exit(1);
    13. }
    14. int main(int argc, char* argv[]){
    15. if (argc != 3) {
    16. printf("Usage: %s \n", argv[0]);
    17. exit(1);
    18. }
    19. WSADATA wsaData; // init socket lib
    20. if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){
    21. ErrorHandling("WSAStartup() error!");
    22. }
    23. int sock = socket(PF_INET, SOCK_STREAM, 0); // create socket
    24. if (sock == -1)
    25. ErrorHandling("socket() error");
    26. struct sockaddr_in serv_addr; // allocate ip, port
    27. memset(&serv_addr, 0, sizeof(serv_addr));
    28. serv_addr.sin_family = AF_INET;
    29. serv_addr.sin_addr.s_addr = inet_addr(argv[1]);
    30. serv_addr.sin_port = htons(atoi(argv[2]));
    31. if (connect(sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1){ // connect
    32. ErrorHandling("connect() error");
    33. }
    34. else {
    35. puts("Connected");
    36. }
    37. for(int i = 0; i < 3; i++) {
    38. char msg[BUF_SIZE];
    39. memset(msg, 0, BUF_SIZE);
    40. fputs("Input message: ", stdout);
    41. fgets(msg + Len_SIZE, BUF_SIZE - Len_SIZE, stdin); // input message
    42. int len = strlen(msg + Len_SIZE);
    43. memcpy(msg, &len, Len_SIZE);
    44. send(sock, msg, Len_SIZE + len, 0); // send message to server
    45. int recv_len = 0, msg_len = 0, recv_cnt = 0;
    46. while (recv_len == 0 || recv_len < msg_len + Len_SIZE) {
    47. recv_cnt = recv(sock, (char*)&msg, BUF_SIZE, 0);
    48. recv_len += recv_cnt;
    49. if (recv_len >= Len_SIZE) {
    50. memcpy(&msg_len, msg, Len_SIZE);
    51. }
    52. }
    53. msg[recv_len] = '\0';
    54. printf("Message from server: %s", msg + Len_SIZE);
    55. }
    56. closesocket(sock);
    57. return 0;
    58. }

    1-3--编译运行

    1. # 服务器端
    2. gcc string_server_win.c -o string_server_win -lwsock32
    3. string_server_win 9190
    4. # 客户端
    5. gcc string_client_win.c -o string_client_win -lwsock32
    6. string_client_win 127.0.0.1 9190

    1-4--基于 linux 实现

    项目链接:Chapter5

    2--基于TCP实现文件传输

  • 相关阅读:
    YOLOv5,YOLOv8添加ASFF(自适应空间特征融合)
    RecyclerView 空白区域点击事件
    centos7安装cdh6.3.2-附带安装包
    android-适配方案-密度适配-最小宽度限定符
    ffmpeg@音视频工具@音视频合并
    人员定位系统如何构建企业安全防护体系?
    基于nodejs+vue美食外卖推荐网站系统源码
    【DR_CAN-MPC学习笔记】1.最优化控制和MPC基本概念
    Springboot引入jasypt实现加解密
    分析基于解析物理模型的E模式p沟道GaN高电子迁移率晶体管(H-FETs)
  • 原文地址:https://blog.csdn.net/weixin_43863869/article/details/132701366