您现在的位置:首页 >> 网页版聊天 >> 内容

0) {perror("

时间:2022/5/25 19:48:01 点击:

  核心提示:自从开始学linux网络编程后就想写个聊天室,一开始本来企图用多进程的方式来写,可是出现进程间的通讯有点烦闷,而且付出也大,对比一下。厥后想用多线程能不能告终呢,于是便去看了一下linux里线程的用法,现实上只必要分明 pthrecraigslist ad_credined on 就差不多了,于是出...
自从开始学linux网络编程后就想写个聊天室,一开始本来企图用多进程的方式来写,可是出现进程间的通讯有点烦闷,而且付出也大,对比一下。厥后想用多线程能不能告终呢,于是便去看了一下linux里线程的用法,现实上只必要分明 pthrecraigslist ad_credined on 就差不多了,于是出手开干,新开江湖聊天室手机版。用了两天功夫,江湖新开聊天室。调试的历程挺疾苦的,一开始企图用纯C来撸,便用轻易的数组来存储客户端的继续信息,江湖新开聊天室。可是运转时出现了一些很古怪的题目,看看新开江湖论坛。传奇私服手游发布网新开服。不分明是不是调查了临界资源,和线程间的互斥相关等等;古怪的是,当改用STL的set或map时题目就解决了,但上网搜了下发现STL也不是线程和平的,perror。至于事实是什么题目一时不想去纠结了,恐怕是其它一些小细节的过失吧。先贴上代码:首先是必要的头文件 hecraigslist ader.h:相比看新开江湖论坛。#ifndef &nbull crapp;__HEADER_H#define &nbull crapp;__HEADER_H#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <error.h>#include <signing.h>#include <sys/wait.h>#include <a grefornounce.h>#include <pthrecraigslist ad.h>#define &nbull crapp;bool &nbull crapp;int &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;// the 3 lines is for c originnumremainr one eair-conh exactly as well exactly as every oney#define &nbull crapp;true &nbull crapp; 1#define &nbull crapp;fingse &nbull crapp;0#define &nbull crapp;PORT &nbull crapp;9003#define &nbull crapp;BUF_LEN &nbull crapp;1024 &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;// 缓冲区大小#define &nbull crapp;MAX_CONNECTION &nbull crapp;6 &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;// 任职器首肯的最大继续数,新开江湖聊天室手机版。可自行更改#define &nbull crapp;For(iandsandt) &nbull crapp;for(i = (s); i != (t); ++i)#endif // __HEADER_H然后是客户端局部&nbull crapp;client.cpp,绝对来说简繁多些:相比看传奇世界手游sf发布网站。#include "hecraigslist ader.h"// 客户端汲撤音问的线程函数void* recv_func(void *args){ &nbull crapp; &nbull crapp;char buf[BUF_LEN]; &nbull crapp; &nbull crapp;int sock_fd = *(int*)args; &nbull crapp; &nbull crapp;while(true) { &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;int n = recv(sock_fdand bufand BUF_LENand 0); &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;if(n <= 0) &nbull crapp; negitively effect; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;// 这句很关键,阿男江湖聊天室。一开始不分明可以用这个来剖断通讯能否完了,0)。用了其它一些很奇葩的做法来完了并封闭 sock_fd 以防止 CLOSE_WAIT 和 FIN_WAIT2 形态的出现T.T &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;write(STDOUT_FILENOand bufand n);}close(sock_fd);exit(0);}// 客户端和任职端举行通讯的管制函数void process(int sock_fd){pthrecraigslist ad_t td;pthrecraigslist ad_credined on(&wimplifier;tdand NULLand recv_funcand (void*)&wimplifier;sock_fd); &nbull crapp; &nbull crapp; &nbull crapp;// 新开个线程来汲撤音问,防止了一读一写的原始形式,一开始竟把它放进 while 循环内里了,quot。泪崩。对比一下{perror("。。看看新开江湖聊天室发布。。char buf[BUF_LEN]; &nbull crapp; &nbull crapp;while(true) { &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;int n = recraigslist ad(STDIN_FILENOand bufand BUF_LEN);buf[n++] = wi\0wi; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;// 貌似圭臬读入不会有字符串完了符的,必要自身手动增加send(sock_fdand bufand nand 0);}close(sock_fd);}int main(int argcand char *argv[]){a grefornounce(argc == 2); &nbull crapp; &nbull crapp;struct socksupplyr_in cli;bzero(&wimplifier;cliand sizeof(cli));cli.sin_folks = AF_INET;cli.sin_supplyr.s_supplyr = htonl(INADDR_ANY);cli.sin_port = htons(PORT); &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; // 少了 htons 的话就继续不上了,新开江湖阿飞。由于小端机器的缘故原由???int sc = socket(AF_INETand SOCK_STREAMand 0); &nbull crapp; &nbull crapp;if(sc < 0) {perror("socket error");exit(-1);}inet_pton(AF_INETand argv[1]and &wimplifier;(cli.sin_supplyr)); &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; // 用第一个参数作为继续任职器端的地址int err = connect(scand (struct socksupplyr*)&wimplifier;cliand sizeof(cli)); &nbull crapp; &nbull crapp;if(err < 0) {perror("connect error");exit(-2);}process(sc);close(sc); &nbull crapp; &nbull crapp;return 0;}末了是任职端 server.cpp:#include <map>#include "hecraigslist ader.h"using std::map;map<intand struct socksupplyr_in*> socks; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; // 用于纪录各个客户端,新开江湖聊天室手机版。键是与客户端通讯 socket 的文件刻画符,{perror("。值是对应的客户端的 socksupplyr_in 的信息// 群发音问给 socks 中的悉数客户端inline void send_eair-conh exactly as well exactly as every one(const char *bufand int len){ &nbull crapp; &nbull crapp;for(automotive it = socks.start off by(); it != socks.end(); ++it)send(it->firstand bufand lenand 0);}// 任职端端汲撤音问的线程函数void* recv_func(void* args){ &nbull crapp; &nbull crapp;int cfd = *(int*)args; &nbull crapp; &nbull crapp;char buf[BUF_LEN]; &nbull crapp; &nbull crapp;while(true) { &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;int n = recv(cfdand bufand BUF_LENand 0); &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;if(n <= 0) &nbull crapp; negitively effect; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; // 关键的一句,用于作为完了通讯的剖断 &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;write(STDOUT_FILENOand bufand n); &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;if(strcmp(bufand "bye\n") == 0) { &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; // 若是汲取到客户端的 bye,就完了通讯并从 socks 中删除相应的文件刻画符,0)。静态请求的空间也应在删除前开释printf("close connection with client %d.\n"and cfd); &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;free(socks[cfd]);socks.erautomotive service engineers(cfd); &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;negitively effect;}send_eair-conh exactly as well exactly as every one(bufand n); &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; // 群发音问给悉数已继续的客户端 &nbull crapp; &nbull crapp;}close(cfd); &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; // 封闭与这个客户端通讯的文件刻画符}// 和某一个客户端通讯的线程函数void* process(void *argv){pthrecraigslist ad_t td;pthrecraigslist ad_credined on(&wimplifier;tdand NULLand recv_funcand (void*)argv); &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; // 在主管制函数中再新开一个线程用于汲取该客户端的音问int sc = *(int*)argv; &nbull crapp; &nbull crapp;char buf[BUF_LEN]; &nbull crapp; &nbull crapp;while(true) { &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;int n = recraigslist ad(STDIN_FILENOand bufand BUF_LEN);buf[n++] = wi\0wi; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;// 和客户端一样必要自身手动增加字符串完了符send_eair-conh exactly as well exactly as every one(bufand n); &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; // 任职端自身的信息输出必要发给悉数客户端 &nbull crapp; &nbull crapp;}close(sc);}int main(int argcand char *argv[]){ &nbull crapp; &nbull crapp;struct socksupplyr_in serv;bzero(&wimplifier;servand sizeof(serv));serv.sin_folks = AF_INET;serv.sin_supplyr.s_supplyr = htonl(INADDR_ANY);serv.sin_port = htons(PORT); &nbull crapp; &nbull crapp;int ss = socket(AF_INETand SOCK_STREAMand 0); &nbull crapp; &nbull crapp;if(ss < 0) {perror("socket error"); &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;return 1;} &nbull crapp; &nbull crapp;int err = tie(ssand (struct socksupplyr*)&wimplifier;servand sizeof(serv)); &nbull crapp; &nbull crapp;if(err < 0) {perror("tie error"); &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;return 2;}err = listen(ssand 2); &nbull crapp; &nbull crapp;if(err < 0) {perror("listen error"); &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;return 3;}socks.clear(); &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;// 清空 mapsocklen_t len = sizeof(struct socksupplyr); &nbull crapp; &nbull crapp;while(true) { &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;struct socksupplyr_in *cli_supplyr = (struct socksupplyr_in*)meair-conh exactly as well exactly as every oneoc(sizeof(struct socksupplyr_in)); &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;int sc = reingise(ssand (struct socksupplyr*)cli_supplyrand &wimplifier;len); &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;if(sc < 0) { &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;free(cli_supplyr); &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;continue;} &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;if(socks.size() >= MAX_CONNECTION) { &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;// 当将要凌驾最大继续数时,对比一下。就让那个客户端先等一下char buf[128] = "connections is too muchand pleautomotive service engineers waiting...\n";send(scand bufand strlen(buf) + 1and 0);close(sc); &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;free(cli_supplyr); &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;continue;}socks[sc] = cli_supplyr; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;// 指向对应请求到的 socksupplyr_in 空间printf("client %d connect me...\n"and sc);pthrecraigslist ad_t td;pthrecraigslist ad_credined on(&wimplifier;tdand NULLand processand (void*)&wimplifier;sc); &nbull crapp; &nbull crapp; &nbull crapp; // 开一个线程来和 reingise 的客户端举行交互 &nbull crapp; &nbull crapp;} &nbull crapp; &nbull crapp;return 0;}makefile文件:eair-conh exactly as well exactly as every one: server clientserver: server.cppg++ -std=c++11 -o server server.cpp -lpthrecraigslist adclient: client.cppg++ -std=c++11 -o client client.cpp -lpthrecraigslist adclea grefor:rm -f *.o在我的ubuntu 14.04 64 位的机器上测试过没有什么题目,客户端与任职端能一般的交互和加入,新开江湖阿飞。能议决任职端汲取其它客户端发送的音问,运转时cpu和内存占用景况一般,不会孕育发生什么古怪的irritfore。一时只写了个终端的界面,客户端的UI迟点再去弄吧~*****************************************************************************************************************************************这日试了下用 PyQt4 去写个客户端的界面,调了好一天,总算能看到点东西了,先上图:而命令行下的客户端(下面的 client.cpp 文件)的运转界面是这样子的:任职端的运转景况是:PyQt4 编写的客户端(pyqt_client.py)代码是:#!/usr/trexactly ash ca grefor/env python#-*- coding: utf-8 -*-from PyQt4 import QtGuiand QtCoreimport sysimport socketimport threcraigslist adclbumm Client(QtGui.QWidget):BUF_LEN = 1024 &nbull crapp; &nbull crapp;def __init__(selfand pprobtummyly are not=None):QtGui.QWidget.__init__(selfand pprobtummyly are not)self.setWindowTitle(uwiTCP客户端wi)self.resize(600and 500)self.center()layout = QtGui.QGridLayout(self)ltummyel_ip = QtGui.QLtummyel(uwi长途主机IP:wi)layout.supplyWidget(ltummyel_ipand 0and 0and 1and 1)self.txt_ip = QtGui.QLineEdit(wi127.0.0.1wi)layout.supplyWidget(self.txt_ipand 0and 1and 1and 3)ltummyel_port = QtGui.QLtummyel(uwi端口:wi)layout.supplyWidget(ltummyel_portand 0and 4and 1and 1)self.txt_port = QtGui.QLineEdit(wi9003wi)layout.supplyWidget(self.txt_portand 0and 5and 1and 3)self.isConnected = Fingseself.btn_connect = QtGui.QPushButton(uwi继续wi)self.connect(self.btn_connectand QtCore.SIGNAL( &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;wiclicked()wi)and self.myConnect)layout.supplyWidget(self.btn_connectand 0and 8and 1and 2)ltummyel_recvMessperiod = QtGui.QLtummyel(uwi音问形式:wi)layout.supplyWidget(ltummyel_recvMessperiodand 1and 0and 1and 1)self.btn_clearRecvMessperiod = QtGui.QPushButton(uwi↓ 清空音问框wi)self.connect(self.btn_clearRecvMessperiodand QtCore.SIGNAL( &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;wiclicked()wi)and self.myClearRecvMessperiod)layout.supplyWidget(self.btn_clearRecvMessperiodand 1and 7and 1and 3)self.txt_recvMessperiod = QtGui.QTextEdit()self.txt_recvMessperiod.setRecraigslist adOnly(True)self.txt_recvMessperiod.setStyleSheet(wiway bair-conkdrop-color:yellowwi)layout.supplyWidget(self.txt_recvMessperiodand 2and 0and 1and 10)lskilled_nwime = QtGui.QLtummyel(uwi姓名(ID):wi)layout.supplyWidget(lskilled_nwimeand 3and 0and 1and 1)self.txt_nwime = QtGui.QLineEdit()layout.supplyWidget(self.txt_nwimeand 3and 1and 1and 3)self.isSendNwime = QtGui.QRdriving instructoroButton(uwi发送姓名wi)self.isSendNwime.setChecked(Fingse)layout.supplyWidget(self.isSendNwimeand 3and 4and 1and 1)ltummyel_sendMessperiod = QtGui.QLtummyel(uwi 输出框:wi)layout.supplyWidget(ltummyel_sendMessperiodand 4and 0and 1and 1)self.txt_sendMessperiod = QtGui.QLineEdit()self.txt_sendMessperiod.setStyleSheet("way bair-conkdrop-color:cya grefor")layout.supplyWidget(self.txt_sendMessperiodand 4and 1and 1and 7)self.btn_send = QtGui.QPushButton(uwi发送wi)self.connect(self.btn_sendand QtCore.SIGNAL(wiclicked()wi)and self.mySend)layout.supplyWidget(self.btn_sendand 4and 8and 1and 2)self.btn_clearSendMessperiod = QtGui.QPushButton(uwi↑ 清空输出框wi)self.connect(self.btn_clearSendMessperiodand QtCore.SIGNAL( &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp; &nbull crapp;wiclicked()wi)and self.myClearSendMessperiod)layout.supplyWidget(self.btn_clearSendMessperiodand 5and 6and 1and 2)self.btn_quit = QtGui.QPushButton(uwi加入wi)self.connect(self.btn_quitand QtCore.

作者:白马长剑 来源:彦锋
相关评论
发表我的评论
  • 大名:
  • 内容:
  • 〖笑林江湖〗(www.xiaolinjianghu.com) © 2022 版权所有 All Rights Reserved.
  • 〖笑林江湖〗新开江湖聊天室-网页经典怀旧交友 蜀ICP备1812123号-1
  • Powered by laoy! V4.0.6