linux下socket實現多個客戶端與伺服器的通訊
學習完《UNIX環境高階程式設計》套接字一章的內容之後,自己實現了單個客戶端與伺服器的通訊程式,後面想想要是多個客戶端如何與伺服器通訊呢?這就有了這篇文章。
伺服器端程式:
客戶端程式:#include<stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <netdb.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #include <unistd.h> #include <arpa/inet.h> #include <fcntl.h> #include <pthread.h> #define BUFLEN 128 #define QLEN 10 #define DATALEN 200 #define SERVPORT 48800 #define HOST_NAME_MAX 256 #define IPLEN 16 //store accept id of client connect to server int acceptfd[QLEN]; //number of client connect to server int acceptnum = 0; //information from main thread to created thread struct threadinfo { int clfd; char ipaddr[IPLEN]; int port; }; void sys_err(char *errinfo) { if(NULL == errinfo) { return; } perror("errinfo"); exit(0); } int initsrver(int type, const struct sockaddr *addr, socklen_t alen, int qlen) { int fd; int err = 0; int reuse = -1; if((fd = socket(addr->sa_family, type, 0)) < 0) { return -1; } //set socket option if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int)) < 0) goto errout; if(bind(fd, addr, alen) < 0) goto errout; if(type == SOCK_STREAM || type == SOCK_SEQPACKET) { //listen if(listen(fd, qlen) < 0) goto errout; } return fd; errout: err = errno; close(fd); errno = err; return -1; } void *recvmessage(void *arg) { char buf[BUFLEN]; char recvtitle[DATALEN] = "receive from "; int n; struct threadinfo *ti = arg; memset(buf, 0, BUFLEN); sprintf(recvtitle, "%s%s:%d ", recvtitle, ti->ipaddr, ti->port); while((n = recv(ti->clfd, buf, BUFLEN, 0)) > 0) { write(STDOUT_FILENO, recvtitle, strlen(recvtitle)); write(STDOUT_FILENO, buf, n); memset(buf, 0, BUFLEN); } if(n < 0) printf("recv error\n"); } void *acceptThread(void *sockfd) { int clfd; const char *addr; char buf[BUFLEN]; int n; char abuf[INET_ADDRSTRLEN]; struct sockaddr_in clientsockaddr; int clientlen; int err; pthread_t recvtid; struct threadinfo ti; clientlen = sizeof(clientsockaddr); //always accept new client to accept a lot of client while(1) { if((clfd = accept(*(int *)sockfd, (struct sockaddr *)&clientsockaddr, &clientlen)) < 0) sys_err("accept error"); printf("%s:%d login in to server\n", inet_ntoa(clientsockaddr.sin_addr), clientsockaddr.sin_port); //when accept client, store it's accept id acceptfd[acceptnum++] = clfd; //create thread to receive message of every client ti.clfd = clfd; strcpy(ti.ipaddr, inet_ntoa(clientsockaddr.sin_addr)); ti.port = clientsockaddr.sin_port; if((err = pthread_create(&recvtid, NULL, recvmessage, &ti)) != 0) sys_err("pthread_create recvmessage error"); } } int communication(int sockfd) { int clfd; pid_t pid; char buf[BUFLEN]; int fd; int err; pthread_t acpttid; int i; memset(buf, 0, BUFLEN); //create thread to accept client, always accept to accept a lot of client if((err = pthread_create(&acpttid, NULL, acceptThread, &sockfd)) != 0) sys_err("pthread_create acceptThread error"); //send message to client, but only send the same mesage to all connected client now memset(buf, 0, BUFLEN); while(1) { if(fgets(buf, BUFLEN, stdin) != NULL) { //print the num of accept client connect to server printf("acceptnum: %d\n", acceptnum); for (i = 0; i < acceptnum; ++i) { send(acceptfd[i], buf, strlen(buf), 0); } memset(buf, 0, BUFLEN); } } close(clfd); } int main(int argc, char *argv[]) { struct sockaddr_in serversockaddr, clientsockaddr; int sockfd, clientfd; int err, n; if(argc != 1) { printf("usage: %s\n", argv[0]); exit(0); } serversockaddr.sin_family = AF_INET; serversockaddr.sin_port = htons(SERVPORT); serversockaddr.sin_addr.s_addr = INADDR_ANY; bzero(&(serversockaddr.sin_zero), 8); if((sockfd = initsrver(SOCK_STREAM, (struct sockaddr *)&serversockaddr, sizeof(struct sockaddr), QLEN)) > 0) { //start communication communication(sockfd); exit(0); } exit(0); }
#include<stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <netdb.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #include <unistd.h> #include <arpa/inet.h> #include <fcntl.h> #include <pthread.h> #define SERVPORT 48800 #define MAXSLEEP 128 #define BUFLEN 128 #define DATALEN 200 int connect_retry(int domain, int type, int protocol, const struct sockaddr *addr) { int numsec, fd; //try to connect with exponential backoff for(numsec = 1; numsec <= MAXSLEEP; numsec <<= 1) { if((fd = socket(domain, type, protocol)) < 0) return -1; if(connect(fd, addr, sizeof(struct sockaddr)) == 0) { return fd; } close(fd); //delay before trying again if(numsec <= MAXSLEEP/2) sleep(numsec); } return -1; } void *sendmessage(void *arg) { int sockfd; char buf[BUFLEN]; sockfd = *(int *)arg; memset(buf, 0, BUFLEN); while(fgets(buf, BUFLEN, stdin) != NULL) { send(sockfd, buf, strlen(buf), 0); memset(buf, 0, BUFLEN); } } void communication(int sockfd) { int n; pid_t pid; char buf[BUFLEN]; char *recvtitle = "received from server: "; int fd; int err; pthread_t tid; memset(buf, 0, BUFLEN); //create thread to send message if(err = pthread_create(&tid, NULL, sendmessage, &sockfd)) { printf("pthread_create error\n"); exit(0); } //receive message while(1) { while((n = recv(sockfd, buf, BUFLEN, 0)) > 0) { write(STDOUT_FILENO, recvtitle, strlen(recvtitle)); write(STDOUT_FILENO, buf, n); memset(buf, 0, BUFLEN); } if(n < 0) printf("recv error\n"); } } int main(int argc, char *argv[]) { int sockfd, err; struct sockaddr_in serversockaddr; const char *addr; char abuf[INET_ADDRSTRLEN]; struct hostent *host; if(argc != 2) { printf("usage: %s hostname\n", argv[0]); exit(0); } if((host = gethostbyname(argv[1])) == NULL) { perror("gethostbyname"); exit(0); } serversockaddr.sin_family = AF_INET; serversockaddr.sin_port = htons(SERVPORT); serversockaddr.sin_addr = *((struct in_addr *)host->h_addr); bzero(&(serversockaddr.sin_zero), 0); if((sockfd = connect_retry(serversockaddr.sin_family, SOCK_STREAM, 0, (struct sockaddr *)&serversockaddr)) < 0) { err = errno; } else { communication(sockfd); exit(0); } printf("can't connect to %s\n", argv[1]); exit(0); }
相關推薦
linux下socket實現多個客戶端與伺服器的通訊
學習完《UNIX環境高階程式設計》套接字一章的內容之後,自己實現了單個客戶端與伺服器的通訊程式,後面想想要是多個客戶端如何與伺服器通訊呢?這就有了這篇文章。 伺服器端程式: #include<stdio.h> #include <stdlib.h&g
Java Socket多個客戶端與伺服器通訊
client程式碼: package com.cqut.test4; import java.io.*; import java.net.Socket; import java.net.SocketException; import java.net.U
linux下socket程式設計 select實現非阻塞模式多臺客戶端與伺服器通訊
select函式原型如下: int select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); select系統呼叫是用來讓我們的程式
Java Socket實現多個客戶端連線同一個服務端
使用Socket實現多個客戶端和同一客戶端通訊;首先客戶端連線服務端傳送一條訊息,服務端接收到訊息後進行處理,完成後再回復客戶端一條訊息。本人通過自己的思維編寫了一份服務端和客戶端實現的程式碼,望能與大家相互學習,共同進步。 服務端程式碼 /** * Socket服務
socket實現多個客戶端連線在一個伺服器上
1、使用socekt通訊一般步驟 1)伺服器端:socker()建立套接字,繫結(bind)並監聽(listen),用accept()等待客戶端連線。 2)客戶端:socker()建立套接字,連線(connect)伺服器,連線上後使用send()和recv(
LInux中利用執行緒實現多個客戶端和伺服器端進行通訊
上一篇博文講了如何利用子程序實現多個客戶端和伺服器端進行通訊, 那麼,這一篇部落格就來實現一下如何利用執行緒實現多個客戶端和伺服器端進行通訊 程式碼實現: ser1.c #include <
使用多線程實現多個客戶端與服務端通信1
runnable system 處理異常 封裝 端口被占用 直接 客戶端連接 i++ 應用程序 Server.java package socket; import java.io.BufferedReader;import java.io.IOException;impo
java--實現多個客戶端與服務端連線
在客戶端與服務端的簡單連線上進行了略微的新增,實現了多個客戶端與服務端的連線 目的: 多個客戶端與服務端的連線,實現服務端發訊息客戶端可以接受到 程式碼: 服務端 import java.io.IOE
Linux c==TCP的多個客戶端連線伺服器 (20)
通過父子程序實現TCP的多個客戶端連線伺服器 tcp_sever_fork.c #include <stdio.h> #include <string.h> #i
select實現多個客戶機與伺服器之間的通訊
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <assert.h> #include <sys/select.h> #incl
TCP實現多個客戶端同時向同一個伺服器端傳送圖片,也可以同一個客戶端多次向伺服器傳送圖片。當上傳圖片大於一定的限度(這裡指定為了10k)時,則停止上傳,將已經接收到但未接收完的檔案刪除。
伺服器端: //多使用者上傳圖片 import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public class UploadPicServer1 { public sta
tcp 多路複用實現 兩個客戶端之間的通訊
/******************************* 伺服器端 ****************************/ #include <stdio.h> #include <stdlib.h> #include <neti
SOCKET讀取多個客戶端下面多個基站下面多個手環傳送的資料(驗收專案版本)
之前,本人,發了一大堆關於socket 多執行緒 客戶端 的一大堆博文,有理論的也有實現版本的,有缺陷有成功的! 但是,今天我要說的是,之前的關於socket博文的,都有誤區,而且達不上真正驗收專案的標準!! 今天是2018/10/7 17:09:00,我真正實現了這個功
linux下如何實現多個定時器
最近在linux下寫一個庫,是給別人用的,要用到定時器這個功能,而且是多定時器任務的,在windows下實現是很方便的,但是 在linux下就遇到了問題,linux下一個程序只能有一個定時器,如果我用了定時器去實現我的任務,那肯定是沒問題的,如果用我庫的人自己也建立了一個定
socket 存在多個客戶端時,一對一連線
1、連線的客戶端實體類package com.example.demo.socket3; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader;
Unity中的Socket通訊(多個客戶端的非同步通訊)
using UnityEngine; using System; using System.Net; using System.Net.Sockets; using System.Collections; using System.Text; using System.Collections.Generic;
(二)用多執行緒管理TCP多個客戶端連線伺服器
該程式的服務端大概工作邏輯如左圖: 首先說說這個程式的作用:這個程式可用於多個客戶端通過連線伺服器來互相通訊。如qq群聊。當一個客戶端有資訊發過來後,服務端就會通過客戶端佇列轉發給其他客戶端 先上程式碼: //TCP服務端 #include"myhead.h" struc
多個客戶端之間的通訊
伺服器 #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/socket.h> #include &
java_多執行緒_socket通訊_多個客戶端傳送,伺服器響應
/** * 伺服器端不斷接受請求 * 接受一個請求開啟一段執行緒 */ package 練習0927; import java.io.BufferedReader; import java.io.IOException; import java.io.InputSt
五、通過Protobuf整合Netty實現對協議訊息客戶端與伺服器通訊實戰
目錄 一、Protocol Buffers 是什麼? 二、Protocol Buffers 檔案和訊息詳解 三、專案實戰,直接掌握的protobuf應用。 一、Protocol Buffers 是什麼? 1、官網翻譯