Linux環境下實現簡單TCP通信(c)

具體代碼實現

server.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>#define PORT 8080
#define BUFFER_SIZE 1024void handle_client(int client_socket) {char buffer[BUFFER_SIZE];while(1) {memset(buffer, 0, BUFFER_SIZE);// 接收客戶端消息int bytes_received = recv(client_socket, buffer, BUFFER_SIZE, 0);if (bytes_received <= 0) {printf("Client disconnected or error occurred.\n");break;}printf("Client: %s", buffer);// 檢查是否要結束通信if (strncmp(buffer, "exit", 4) == 0) {printf("Exit command received. Closing connection.\n");break;}// 發送響應printf("Server: ");fgets(buffer, BUFFER_SIZE, stdin);send(client_socket, buffer, strlen(buffer), 0);// 檢查服務器是否要結束通信if (strncmp(buffer, "exit", 4) == 0) {printf("Server initiated exit. Closing connection.\n");break;}}close(client_socket);
}int main() {int server_fd, client_socket;struct sockaddr_in address;int opt = 1;int addrlen = sizeof(address);// 創建socket文件描述符if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {perror("socket failed");exit(EXIT_FAILURE);}// 設置socket選項if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {perror("setsockopt");exit(EXIT_FAILURE);}address.sin_family = AF_INET;address.sin_addr.s_addr = INADDR_ANY;address.sin_port = htons(PORT);// 綁定socket到端口if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {perror("bind failed");exit(EXIT_FAILURE);}// 開始監聽if (listen(server_fd, 3) < 0) {perror("listen");exit(EXIT_FAILURE);}printf("Server listening on port %d...\n", PORT);// 接受連接if ((client_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {perror("accept");exit(EXIT_FAILURE);}printf("Connection accepted from %s:%d\n", inet_ntoa(address.sin_addr), ntohs(address.sin_port));// 處理客戶端通信handle_client(client_socket);printf("Closing server...\n");close(server_fd);return 0;
}

client.c

client分為兩版,分別是實現本地通信和與特定ip地址的server通信

本地通信

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>#define PORT 8080
#define BUFFER_SIZE 1024void communicate(int sock) {char buffer[BUFFER_SIZE];while(1) {// 發送消息printf("Client: ");fgets(buffer, BUFFER_SIZE, stdin);send(sock, buffer, strlen(buffer), 0);// 檢查是否要結束通信if (strncmp(buffer, "exit", 4) == 0) {printf("Exiting...\n");break;}// 接收服務器響應memset(buffer, 0, BUFFER_SIZE);int bytes_received = recv(sock, buffer, BUFFER_SIZE, 0);if (bytes_received <= 0) {printf("Server disconnected or error occurred.\n");break;}printf("Server: %s", buffer);// 檢查服務器是否要結束通信if (strncmp(buffer, "exit", 4) == 0) {printf("Server initiated exit. Closing connection.\n");break;}}
}int main() {int sock = 0;struct sockaddr_in serv_addr;// 創建socketif ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {printf("\n Socket creation error \n");return -1;}serv_addr.sin_family = AF_INET;serv_addr.sin_port = htons(PORT);// 將IPv4地址從文本轉換為二進制形式if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {printf("\nInvalid address/ Address not supported \n");return -1;}// 連接到服務器if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {printf("\nConnection Failed \n");return -1;}printf("Connected to server\n");// 開始通信communicate(sock);printf("Closing client...\n");close(sock);return 0;
}

特定IP通信

與上面相比,修改了客戶端代碼中的目標服務器地址

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>#define PORT 8080
#define BUFFER_SIZE 1024void communicate(int sock) {char buffer[BUFFER_SIZE];while(1) {// 發送消息printf("Client: ");fgets(buffer, BUFFER_SIZE, stdin);send(sock, buffer, strlen(buffer), 0);// 檢查是否要結束通信if (strncmp(buffer, "exit", 4) == 0) {printf("Exiting...\n");break;}// 接收服務器響應memset(buffer, 0, BUFFER_SIZE);int bytes_received = recv(sock, buffer, BUFFER_SIZE, 0);if (bytes_received <= 0) {printf("Server disconnected or error occurred.\n");break;}printf("Server: %s", buffer);// 檢查服務器是否要結束通信if (strncmp(buffer, "exit", 4) == 0) {printf("Server initiated exit. Closing connection.\n");break;}}
}int main(int argc, char const *argv[]) {int sock = 0;struct sockaddr_in serv_addr;// 檢查參數if (argc != 2) {printf("Usage: %s <server_ip>\n", argv[0]);return -1;}// 創建socketif ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {printf("\n Socket creation error \n");return -1;}serv_addr.sin_family = AF_INET;serv_addr.sin_port = htons(PORT);// 將用戶輸入的IP地址從文本轉換為二進制形式if (inet_pton(AF_INET, argv[1], &serv_addr.sin_addr) <= 0) {printf("\nInvalid address/ Address not supported \n");return -1;}// 連接到服務器if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {printf("\nConnection Failed to %s:%d\n", argv[1], PORT);return -1;}printf("Connected to server at %s:%d\n", argv[1], PORT);// 開始通信communicate(sock);printf("Closing client...\n");close(sock);return 0;
}

功能說明

  • 服務器和客戶端可以持續收發消息,直到輸入"exit"命令
  • 服務器和客戶端都可以主動結束通信
  • 每次發送消息前會顯示提示符(Client: 或 Server:)
  • 任何一方輸入"exit"都會終止通信,且會檢測對方是否斷開連接

具體使用方法

1、編譯

gcc server.c -o server
gcc client.c -o client

2、服務器運行

./server

3、客戶端運行(在另一個終端)

./client					# 本地通信版
./client 目標服務器IP		# 特定IP通信# 要連接本地主機,可以使用127.0.0.1

4、通信

在客戶端或服務器終端輸入消息,按回車發送

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/92572.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/92572.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/92572.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

炫酷圓形按鈕調色器

<!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>圓形按鈕顏色控制器</title><style>bod…

Vue 3 的編譯時優化如何改寫 DOM 操作規則

在現代前端開發中&#xff0c;框架級優化正悄然改變我們處理性能瓶頸的方式。與手動優化策略不同&#xff0c;Vue 3 的編譯器在構建階段就完成了關鍵性能改造&#xff0c;為 DOM 操作效率帶來質的飛躍。一、虛擬DOM的隱藏成本虛擬DOM&#xff08;Virtual DOM&#xff09;通過內…

Angular初學者入門第二課——.ts、.d.ts、.state.ts的區別(精品)

初次接觸 Angular 實際項目時&#xff0c;發現里邊有很多不同后綴的文件&#xff0c;雖然沒深入研究過&#xff0c;但根據其他編程語言的經驗猜測這應該是通過后綴名來區分文件的作用。后來有時間研究了一下具體的細節和不同點&#xff0c;就有了今天這篇文章&#xff0c;這些知…

進程狀態+進程優先級+進程上下文切換解讀

一、進程狀態 什么是進程狀態&#xff1f;進程狀態指的是在操作系統中進程在生命周期中所處的不同階段。進程狀態有哪些呢&#xff1f;我們可以看到上述圖片 進程狀態分為&#xff1a;創建狀態、就緒狀態、運行狀態、阻塞狀態和終止狀態所有的操作系統在實現進程狀態變化的時候…

Android 原生與 Flutter 通信完整實現 (Kotlin 版)

1. 項目配置 pubspec.yaml 添加依賴 dependencies:flutter:sdk: flutterprovider: ^6.0.52. Flutter 端實現 狀態管理類 // settings_provider.dart import package:flutter/foundation.dart;class SettingsProvider with ChangeNotifier {String _themeColor blue;bool _dark…

數字圖像處理3

圖像線性濾波——目的就是濾去噪聲&#xff0c;但是邊緣會模糊&#xff0c;整體也模糊線性&#xff1a;鄰域平均法&#xff08;4鄰域平均和8鄰域平均&#xff09;用當前運算點所在鄰域的平均值來代替該點的平均值im_for_read"D:\AAAproject\PYproject\EXPERuse\zaosheng.j…

Linux發行版分類與Centos替代品

讓centos7氣的不輕&#xff0c;這玩意兒太老了&#xff0c;什么都不好配置。 目錄Linux 發行版的大致分類1. Red Hat 系列&#xff08;RPM 系&#xff09;2. Debian 系列&#xff08;DEB 系&#xff09;3. Arch 系列4. SUSE 系列CentOS 7 的替代品推薦AlmaLinux 和 Rocky Linux…

大語言模型提示工程與應用:大語言模型對抗性提示安全防御指南

對抗性提示工程 學習目標 理解大語言模型中對抗性提示的風險與防御機制&#xff0c;掌握提示注入、提示泄露和越獄攻擊的檢測方法&#xff0c;培養安全防護意識。 相關知識點 對抗性攻擊類型防御技術 學習內容 1 對抗性攻擊類型 1.1 提示注入 提示注入旨在通過使用巧妙…

避不開的數據拷貝(2)

接著上周未完的話題 避不開的數據拷貝。 既然處理器是通用機器&#xff0c;就沒有專屬數據&#xff0c;所以數據都要從別處調來&#xff0c;這就涉及到了數據搬運&#xff0c;就有了外設的概念。由于不同外設和處理器一起共享數據存儲&#xff0c;時間會花在兩方面&#xff1a…

娃哈哈經銷商“大洗牌”:砍掉年銷300萬以下經銷商

文 | 大力財經據第一財經報道&#xff0c;娃哈哈在宗馥莉“鐵腕”策略推動下&#xff0c;正經歷經銷商體系的重大變革&#xff0c;陸續砍掉年銷低于300萬元的經銷商&#xff0c;方式有時頗為激進&#xff0c;“一刀切”的做法引發諸多爭議&#xff0c;部分經銷商反饋存在款項未…

drippingblues靶機通關練習筆記

前言 將靶機導入到vmware虛擬機上 靶機下載地址&#xff1a;https://download.vulnhub.com/drippingblues/drippingblues.ova 將網段都設置為nat 信息收集 ip端口掃描 netdiscover -r 192.168.25.1/24 --確定ip nmap -A -p- 192.168.25. kalid的ip&#xff1a;1…

QT第三講- 機制、宏、類庫模塊

文章目錄 ?? 一、Qt核心機制與類庫 ?? 1. 元對象系統(Meta-Object System) ? 2. 信號與槽(Signals & Slots) ? 通信機制 ?? 3. 屬性系統(Property System) 動態屬性 例程 類的附加信息 Q_CLASSINFO 例程 ?? 二、全局定義與容器 ?? 1. 全局數據類型與函數…

(LeetCode 每日一題) 869. 重新排序得到 2 的冪 (哈希表+枚舉)

題目&#xff1a;869. 重新排序得到 2 的冪 思路&#xff1a;哈希表枚舉。先預處理出所有的2的冪數&#xff0c;用哈希表來存儲。 C版本&#xff1a; class Solution { public:// 哈希表存儲所有 2的冪數 按升序排列的形式unordered_set<string> st;// 預處理出所有的2…

WebAssembly技術詳解:從瀏覽器到云原生的高性能革命

引言&#xff1a;WebAssembly的誕生與使命 2015年&#xff0c;當Mozilla、Google、Microsoft和Apple四大瀏覽器廠商聯合發布WebAssembly&#xff08;Wasm&#xff09;技術預覽時&#xff0c;業界尚未意識到這將開啟Web性能的新紀元。作為繼HTML、CSS、JavaScript之后的第四種We…

性能解析案例

異步io是內核fd與應用程序直接的關系io 多路復用1.檢測io是否就緒2.read/write消息隊列kafka&#xff1a;1.典型應用 &#xff1a;異步處理&#xff0c;系統解耦&#xff0c;流量削峰&#xff0c;日志處理2.核心原理&#xff1a;kafka體系結構以及讀寫流程3.具體操作&#xff1…

青龍峽拔韭菜

我們一年四季&#xff0c;除了冬天不往山里進&#xff0c;其余季節&#xff0c;只要天氣允許&#xff0c;我們都會進山。在山里拔韭菜&#xff0c;是我們百做不煩的一件事。今年大旱&#xff0c;從五月份上山找韭菜&#xff0c;沒有如愿。直到入秋后&#xff0c;我們再次去青龍…

5、docker鏡像管理命令

1、命令總覽命令&#xff08;含關鍵參數&#xff09;作用出現頻率備注docker buildx build --platform … -t … --push .一次構建并推送多平臺鏡像高頻需先 docker buildx create --usedocker buildx build -o typedocker,destxxx.tar .構建后離線導出 tar 包中頻只導出單平臺…

阿里云ECS云服務器臨時升級帶寬方法

阿里云ECS云服務器臨時升級帶寬方法一、背景與需求二、原理三、操作步驟步驟 0: 準備工作步驟 1: 創建彈性網卡 (ENI)步驟 2: 創建并綁定彈性公網IP (EIP)步驟 3: SSH登錄ECS并切換到高速通道 (eth1)步驟 4: 執行你的高帶寬任務步驟 5: 任務完成&#xff0c;切回默認網卡 (eth0…

Java語言簡介

一.Java語言的起源 Java語言的前身是Oka語言,是美國Sun Microsystems公司于1991年推出的,僅限于公司內部使用的語言。1995年,Sun公司將Oak語言更名為Java語言,并正式向公眾推出。這之后,Java語言不斷更新,其類庫越來越豐富,性能逐步提升,應用領域也顯著拓展,已成為當今…

VUE+SPRINGBOOT從0-1打造前后端-前后臺系統-視頻列表與視頻播放

在現代Web開發中&#xff0c;視頻播放功能已成為許多網站的基本需求。本文將基于Vue.js框架&#xff0c;詳細講解如何實現一個視頻列表與播放器交互的功能模塊。這個組件可以讓用戶點擊列表中的視頻項來播放對應的視頻&#xff0c;并支持再次點擊關閉播放器。功能概述我們實現的…