日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux使用TCP聊天室设计详解,基于linux的TCP网络聊天室设计与实现

發(fā)布時間:2023/12/20 linux 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux使用TCP聊天室设计详解,基于linux的TCP网络聊天室设计与实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

利用Linux實現(xiàn)基于TCP模式的網(wǎng)絡(luò)聊天程序

主要完成的兩大組成部分為:服務(wù)器和客戶端。

服務(wù)器程序主要負(fù)責(zé)監(jiān)聽客戶端發(fā)來的消息。 客戶端需要登錄到服務(wù)器端才可以實現(xiàn)正常的聊天功能。該程序是利用進(jìn)程以及共享內(nèi)存來實現(xiàn)群發(fā)送消息的。

以下簡單分析一下服務(wù)器端和客戶端兩個方面所要完成的任務(wù)。

服務(wù)器的主要功能如下:

在特定的端口上進(jìn)行監(jiān)聽,等待客戶端的連接。 用戶可以配置服務(wù)器端的監(jiān)聽端口。 向連接的客戶端發(fā)送登錄成功信息。 向已經(jīng)連接到服務(wù)器的客戶端的用戶發(fā)送系統(tǒng)消息。 使用TCP多線程并發(fā)服務(wù)器,向在線的所有客戶端發(fā)送消息

客戶端的主要功能如下:

客戶端傳參輸入IP和端口號以及用戶名進(jìn)行注冊 連接到已經(jīng)開啟的服務(wù)的服務(wù)端 用戶可以向所有人發(fā)送信息 用戶可以接受服務(wù)器發(fā)送的系統(tǒng)消息

服務(wù)器功能描述

服務(wù)器主要是負(fù)責(zé)監(jiān)聽客戶端發(fā)送來的消息,利用TCP線程并發(fā)服務(wù)器模型實現(xiàn)對客戶端的監(jiān)聽接收。

服務(wù)器程序的作用為:初始化服務(wù)器程序,持續(xù)監(jiān)聽一個固定的端口,收到客戶的連接后建立一個socket連接,與客戶進(jìn)行通信和信息處理,接收客戶通過socket連接發(fā)送來的數(shù)據(jù),創(chuàng)建一個新的socket;通過socket連接與客戶通信,進(jìn)行響應(yīng)處理,并返回結(jié)果,通信結(jié)束后終端與客戶的連接(關(guān)閉socket);主要的過程為服務(wù)器創(chuàng)建一個共享內(nèi)存空間函數(shù),以及客戶端簡單的界面,利用套接字模型機(jī)制實現(xiàn)服務(wù)器簡易模型的實現(xiàn),利用 socket()創(chuàng)建流式套接字,并可以返回套接自號;利用bind()實現(xiàn)套接字與本地地址相連,listen()通知TCP服務(wù)器準(zhǔn)備好監(jiān)聽客戶端的連接,accept()接收連接,等待客戶端的連接,建立連接之后accept返回新的標(biāo)識客戶端的套接字,運用多線程以及recv()/send()接收發(fā)送數(shù)據(jù);

客戶端功能描述

客戶端主要用來向服務(wù)器端發(fā)送數(shù)據(jù),客戶端程序的作用:初始化客戶程序,連接到某個服務(wù)器上,建立socket連接,通過socket連接向服務(wù)器發(fā)送請求信息,通信結(jié)束后中斷與客戶的連接。主要的實現(xiàn)步驟為:需要定義運行時候需要的參數(shù),同樣利用socket()建立流式套接字,返回套接字號,connect()將套接字與遠(yuǎn)程主機(jī)連接,recv()和send()將套接字上的讀寫數(shù)據(jù)進(jìn)行發(fā)送與接收,close()關(guān)閉套接字,關(guān)閉對話。

c.c

#include

#include

#include

#include #include

#include

#include

#include

#include

#include

#include

#define SIZE 1024

int main(int argc, char *argv[])

{

pid_t pid;

int sockfd,confd;

char buffer[SIZE],buf[SIZE];

struct sockaddr_in server_addr;

struct sockaddr_in client_addr;

struct hostent *host;

short port;

char *name;

//四個參數(shù)

if(argc!=4)

{

fprintf(stderr,"Usage:%s hostname an",argv[0]);

exit(1);

}

//使用hostname查詢host 名字

if((host=gethostbyname(argv[1]))==NULL)

{

fprintf(stderr,"Gethostname errorn");

exit(1);

}

port=atoi(argv[2]);

name=argv[3];

/*客戶程序開始建立 sockfd描述符 */

if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)

{

fprintf(stderr,"Socket Error:%san",strerror(errno));

exit(1);

} else{

printf("Socket successful!n");

}

/*客戶程序填充服務(wù)端的資料 */

bzero(&server_addr,sizeof(server_addr)); // 初始化,置0

server_addr.sin_family=AF_INET; // IPV4

server_addr.sin_port=htons(port); // (將本機(jī)器上的short數(shù)據(jù)轉(zhuǎn)化為網(wǎng)絡(luò)上的short數(shù)據(jù))端口號

server_addr.sin_addr=*((struct in_addr *)host->h_addr); // IP地址

/* 客戶程序發(fā)起連接請求 */

if(confd=connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)

{

fprintf(stderr,"Connect Error:%san",strerror(errno));

exit(1);

}else{

printf("Connect successful!n");

}

/*將客戶端的名字發(fā)送到服務(wù)器端*/

send(sockfd,name,20,0);

/*創(chuàng)建子進(jìn)程,進(jìn)行讀寫操作*/

pid = fork();//創(chuàng)建子進(jìn)程

while(1)

{

/*父進(jìn)程用于發(fā)送信息*/

if(pid > 0)

{

/*時間函數(shù)*/

struct tm *p;

time(&timep);

p = localtime(&timep);

strftime(buffer, sizeof(buffer), "%Y/%m/%d %H:%M:%S", p);

/*輸出時間和客戶端的名字*/

strcat(buffer," nt昵稱 ->");

strcat(buffer,name);

strcat(buffer,":ntt ");

memset(buf,0,SIZE);

fgets(buf,SIZE,stdin);

/*對客戶端程序進(jìn)行管理*/

if(strncmp("e",buf,1)==0)

{

printf("該客戶端下線...n");

strcat(buffer,"退出聊天室!");

if((send(sockfd,buffer,SIZE,0)) <= 0)

{

perror("error send");

}

close(sockfd);

sockfd = -1;

exit(0);

}else

{

strncat(buffer,buf,strlen(buf)-1);

strcat(buffer,"n");

if((send(sockfd,buffer,SIZE,0)) <= 0)

{

perror("send");

}

}

}

else if(pid == 0)

{

/*子進(jìn)程用于接收信息*/

memset(buffer,0,SIZE);

if(sockfd > 0)

{

if((recv(sockfd,buffer,SIZE,0)) <= 0)

{

close(sockfd);

exit(1);

}

printf("%sn",buffer);

}

}

} close(sockfd);

return 0;

}

s.c

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include#define PORT 4395

#define SIZE 1024

#define SIZE_SHMADD 2048

#define BACKLOG 3

int sockfd;

int fd[BACKLOG];

int i=0;

/*********套接字描述符*******/

int get_sockfd()

{ struct sockaddr_in server_addr; if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) { fprintf(stderr,"Socket error:%sna",strerror(errno)); exit(1); }else{

printf("Socket successful!n"); } /*sockaddr結(jié)構(gòu) */

bzero(&server_addr,sizeof(struct sockaddr_in));

server_addr.sin_family=AF_INET;

server_addr.sin_addr.s_addr=htonl(INADDR_ANY);

server_addr.sin_port=htons(PORT);

/*綁定服務(wù)器的ip和服務(wù)器端口號*/

if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)

{ fprintf(stderr,"Bind error:%sna",strerror(errno));

exit(1);

} else{printf("Bind successful!n"); }

/* 設(shè)置允許連接的最大客戶端數(shù) */

if(listen(sockfd,BACKLOG)==-1)

{ fprintf(stderr,"Listen error:%sna",strerror(errno)); exit(1); } else{

printf("Listening.....n"); }

return sockfd;

}

/*創(chuàng)建共享存儲區(qū)*/

int shmid_create()

{ int shmid; if((shmid = shmget(IPC_PRIVATE,SIZE_SHMADD,0777)) < 0) { perror("shmid error!"); exit(1); }

Else printf("shmid success!n");

return shmid;

}

int main(int argc, char *argv[]) { char shmadd_buffer[SIZE_SHMADD],buffer[SIZE]; struct sockaddr_in client_addr;

int sin_size;

pid_t ppid,pid; int new_fd;

int shmid;

char *shmadd;

/***********共享內(nèi)存**************/

shmid = shmid_create();

//映射共享內(nèi)存

shmadd = shmat(shmid, 0, 0);

/*****創(chuàng)建套接字描述符***********/

int sockfd = get_sockfd();

/*循環(huán)接收客戶端*/

while(1)

{ /* 服務(wù)器阻塞,直到客戶程序建立連接 */

sin_size=sizeof(struct sockaddr_in);

if((new_fd=accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size))==-1)

{ fprintf(stderr,"Accept error:%sna",strerror(errno)); exit1); }else{printf("Accept successful!n"); }

fd[i++] = new_fd;

printf("n已連接了客戶端%d : %s:%d n",i , inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

/*把界面發(fā)送給客戶端*/

memset(buffer,0,SIZE);

strcpy(buffer,"n——————————————————Welecom come char ———————————————————————n");

send(new_fd,buffer,SIZE,0);

//創(chuàng)建子進(jìn)程客戶端

ppid = fork(); if(ppid == 0)

{

//將加入的新客戶發(fā)送給所有在線的客戶端/

recv(new_fd,buffer,SIZE,0);

strcat( buffer," 進(jìn)入了聊天室....");

for(i=0;i 0)

{

//父進(jìn)程用于接收信息/

memset(buffer,0,SIZE);

if((recv(new_fd,buffer,SIZE,0)) <= 0)

{

close(new_fd);

exit(1); }

memset(shmadd, 0, SIZE_SHMADD);

strncpy(shmadd, buffer, SIZE_SHMADD);//將緩存區(qū)的客戶端信息放入共享內(nèi)存里

printf(" %sn",buffer);

}

if(pid == 0)

{

//子進(jìn)程用于發(fā)送信息/

sleep(1);//先執(zhí)行父進(jìn)程

if(strcmp(shmadd_buffer,shmadd) != 0)

{

strcpy(shmadd_buffer,shmadd);

if(new_fd > 0)

{

if(send(new_fd,shmadd,strlen(shmadd),0) == -1)

{

perror("send");

}

memset(shmadd, 0, SIZE_SHMADD);

strcpy(shmadd,shmadd_buffer);

}

}

}

}

}

} free(buffer);

close(new_fd);

close(sockfd);

return 0;

}

服務(wù)器進(jìn)行編譯執(zhí)行

客戶端進(jìn)行編譯執(zhí)行

服務(wù)器出現(xiàn)結(jié)果

另外打開一個終端執(zhí)行對客戶端代碼編譯執(zhí)行

總結(jié)

以上是生活随笔為你收集整理的linux使用TCP聊天室设计详解,基于linux的TCP网络聊天室设计与实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。