赞
踩
#include <iostream> #include <cstring> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <pthread.h> #include <unistd.h> #include <cerrno> #include "log.hpp" #define SIZE 1024 uint16_t serverport; std::string serverip; void *tcpSend(void *args) { int sock = *(int *)args; std::string message; while (true) { std::cerr << "请输入你的信息# "; std::getline(std::cin, message); send(sock, message.c_str(), message.size(), 0); } } void *tcpRecv(void *args) { int sock = *(int *)args; char buff[1024]; while (true) { ssize_t s = recv(sock, buff, sizeof(buff) - 1, 0); if (s > 0) { buff[s] = '\0'; printf("%s\n", buff); fflush(stdout); } } } int main(int argc, char *argv[]) { if (argc != 3) { std::cout << "Usage: " << argv[0] << " ip port" << std::endl; exit(1); } int sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { std::cerr << "FATAL " << errno << ":" << strerror(errno); exit(2); } serverport = atoi(argv[2]); serverip = argv[1]; struct sockaddr_in server; memset(&server, 0, sizeof server); server.sin_family = AF_INET; server.sin_port = htons(serverport); server.sin_addr.s_addr = inet_addr(serverip.c_str()); if (connect(sock, (struct sockaddr*)&server, sizeof(server)) == -1) { printf("连接失败 [%d:%s]\n",errno,strerror(errno)); close(sock); exit(1); } LogMessage(NORMAL,"connect success"); pthread_t t1, t2; pthread_create(&t1, nullptr, tcpSend, (void *)&sock); pthread_create(&t2, nullptr, tcpRecv, (void *)&sock); pthread_join(t1, nullptr); pthread_join(t2, nullptr); close(sock); return 0; }
#include "tcp_server.hpp"
int main(int argc,char* argv[])
{
if(argc != 2)
{
std::cout<<"Usage: "<<argv[0]<<" port"<<std::endl;
exit(1);
}
uint16_t port = atoi(argv[1]);
TcpServer* svr = new TcpServer(port);
svr->initServer();
svr->start();
delete svr;
return 0;
}
#ifndef UDP_SERVER_HPP #define UDP_SERVER_HPP #include <iostream> #include <cstring> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unordered_map> #include <unistd.h> #include <signal.h> #include <wait.h> #include "log.hpp" #define SIZE 1024 static void service(int sock, std::string &client_ip, uint16_t &client_port) { char buff[1024]; while (true) { ssize_t s = read(sock, buff, sizeof(buff) - 1); if (s > 0) { buff[s] = '\0'; printf("[%s:%d]# %s\n", client_ip.c_str(), client_port, buff); } else if (s == 0) { LogMessage(NORMAL, "[%s:%d] shutdown, me too!", client_ip.c_str(), client_port); break; } else { LogMessage(ERROR, "read socket error, %d:%s", errno, strerror(errno)); break; } write(sock, buff, strlen(buff)); } } struct ThreadData { int _sock; std::string _ip; uint16_t _port; }; class TcpServer { private: const int gbacklog = 20; public: static void* threadRoutine(void* args) { pthread_detach(pthread_self()); ThreadData* td = (ThreadData*)args; service(td->_sock, td->_ip, td->_port); delete td; return nullptr; } TcpServer(uint16_t port, std::string ip = "0.0.0.0") : _port(port), _listensock(-1),_ip(ip) { } void initServer() { // 创建套接字 _listensock = socket(AF_INET, SOCK_STREAM, 0); if (_listensock < 0) { LogMessage(FATAL, "socket error, %d:%s", errno, strerror(errno)); exit(2); } // 绑定 struct sockaddr_in local; local.sin_family = AF_INET; local.sin_port = htons(_port); local.sin_addr.s_addr = inet_addr(_ip.c_str()); if (bind(_listensock, (struct sockaddr *)&local, sizeof(local)) < 0) { LogMessage(FATAL, "bind error, %d:%s", errno, strerror(errno)); exit(3); } // 建立连接(监听) if (listen(_listensock, gbacklog) < 0) { LogMessage(FATAL, "listen error, %d:%s", errno, strerror(errno)); exit(4); } LogMessage(NORMAL, "init TCP server success, listensock: %d", _listensock); } void start() { signal(SIGCHLD,SIG_IGN);//不理会子进程 v2.1 while (true) { // 获取连接 struct sockaddr_in src; socklen_t len = sizeof(src); int servicesock = accept(_listensock, (struct sockaddr *)&src, &len); std::cout<<servicesock<<std::endl; if (servicesock < 0) { LogMessage(ERROR, "accept error, %d:%s", errno, strerror(errno)); continue; } uint16_t client_port = ntohs(src.sin_port); std::string client_ip = inet_ntoa(src.sin_addr); LogMessage(NORMAL, "link success, [%s:%d]", client_ip.c_str(), client_port); // 获取连接成功,开始通信服务 // v1 单进程循环 //service(servicesock, client_ip, client_port); //v2.0 多进程 // pid_t id = fork(); // if(id == 0) // { // close(_listensock); // service(servicesock, client_ip, client_port); // exit(0); // } // close(servicesock); //v2.1 多进程 // pid_t id = fork(); // if(id == 0) // { // close(_listensock); // if(fork() > 0) exit(0); // service(servicesock, client_ip, client_port); // } // waitpid(id,nullptr,0); // close(servicesock); //v3 多线程 ThreadData* td = new ThreadData; td->_sock = servicesock; td->_ip = client_ip; td->_port = client_port; pthread_t tid; pthread_create(&tid,nullptr,threadRoutine,(void*)td); close(servicesock); } } private: uint16_t _port; std::string _ip; int _listensock; }; #endif
#pragma once #include<iostream> #include<cstdio> #include<cstdarg> #include<ctime> #include<string> #define DEBUG 0 #define NORMAL 1 #define WARNING 2 #define ERROR 3 #define FATAL 4 const char* gLevelMap[]={"DEBUG","NORMAL","WARNING","ERROR","FATAL"}; void LogMessage(int level,const char* format,...) { char stdBuffer[1024] = {'\0'}; time_t timestamp = time(nullptr); snprintf(stdBuffer,sizeof stdBuffer,"[%s] [%ld]",gLevelMap[level],timestamp); char logBuffer[1024] = {'\0'};; va_list args; va_start(args,format); vsnprintf(logBuffer,sizeof logBuffer,format,args); va_end(args); printf("%s%s\n",stdBuffer,logBuffer); }
.PHONY:add
all:tcp_client tcp_server
tcp_client:tcp_client.cc
g++ -o $@ $^ -std=c++11 -l pthread
tcp_server:tcp_server.cc
g++ -o $@ $^ -std=c++11 -l pthread
.PHONY:clean
clean:
rm -f tcp_client tcp_server
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。