Linux下TCP编程

来源:互联网 发布:淘宝售前客服技巧培训 编辑:程序博客网 时间:2024/06/06 22:31

服务器端在Linux环境下。

Server.cpp

#include <iostream>//#include <WinSock2.h>using namespace std;enum{PORT=12345};#ifdef _WIN32  //windows下#include <WinSock2.h>typedef int socklen_t;#else      //Linux下#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>typedef unsigned int SOCKET;#define  INVALID_SOCKET (SOCKET)(~0)#define SOCKET_ERROR (-1)#endifint main(){#ifdef _WIN32   //windows项目下WSADATA wd; //套接字库信息结构体//参数1:套接字库版本号//参数2:输出参数,保存加载的套接字库的相关信息WSAStartup(0X0202,&wd);  //加载套接字#endif//创建socket句柄SOCKET sock=socket(AF_INET,SOCK_STREAM,0);sockaddr_in sa={AF_INET,htons(PORT)};//句柄绑定到端口上int n=bind(sock,(sockaddr*)&sa,sizeof(sa));listen(sock,5); //侦听,参数2:等待连接队列的最大长度socklen_t nLen=sizeof(sa);//int nLen=sizeof(sa);  ******windows下while(true){//等待客户端的连接SOCKET socka=accept(sock,(sockaddr*)&sa,&nLen);cout<<inet_ntoa(sa.sin_addr)<<"-"<<htons(sa.sin_port)<<"登陆"<<endl;while(true){char s[2048];//接收数据n=recv(socka,s,sizeof(s),0);if(n<=0) //未接收到数据时break;s[n]=0;cout<<s<<endl;}cout<<inet_ntoa(sa.sin_addr)<<"-"<<htons(sa.sin_port)<<"退出"<<endl;}return 0;}


客户端在Windows环境下:

Client.cpp

#include <iostream>#include <WinSock2.h>using namespace std;enum{PORT=12345};int main(){WSADATA wd;WSAStartup(0x0202,&wd);SOCKET sock=socket(AF_INET,SOCK_STREAM,0);sockaddr_in sa={AF_INET,htons(PORT)};sa.sin_addr.s_addr=inet_addr("192.168.1.5");  //Linux和windows下均可//sa.sin_addr.S_un.S_addr=inet_addr("192.168.1.5");   //windows下//通过sa连接服务器int n=connect(sock,(sockaddr*)&sa,sizeof(sa)); if(n<0){cout<<GetLastError()<<endl;//cout<<errno<<endl;  ***Linux下return -1;}char s[2048];while(true){cout<<"请输入你要发送的文字[#退出]";cin>>s;if('#'==s[0])break;send(sock,s,strlen(s),0);}return 0;}





先在Linux下编译Server.cpp,运行(服务端,Linux本机地址为192.168.1.5)



再在Windows下编译Client.cpp,运行(客户端,Windows本机地址为:192.168.1.4)

客户端输入文字后,服务器端结果如下,检测到客户端IP及端口号,并接收到发送的数据:





现两端完全在Linux下,并使用封装好的SockLx类

SockLx.h

// SockLx.h : Version 1.1(支持Unicode、支持VS2015和VC6编译环境)//Author:吕鑫老师封装类 (支持Linux开发)//吕鑫老师微博:http://t.qq.com/richmain 吕鑫老师微信:richmain//更多更好的是项目开发视频教程,请登录http://www.baojy.com//////////////////////////////////////////////////////////////////////#pragma once#define _WINSOCK_DEPRECATED_NO_WARNINGS#define _CRT_SECURE_NO_WARNINGS#include <stdlib.h>#ifdef _WIN32#include <WinSock2.h>#include <process.h>#ifdef _UNICODE#include <comdef.h>//#include <WS2tcpip.h>#endiftypedef int socklen_t;typedef void RET_TYPE;#else#include <errno.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <unistd.h>#include <errno.h>#include <string.h>typedef unsigned int SOCKET;#define INVALID_SOCKET  (SOCKET)(~0)#define SOCKET_ERROR            (-1)#ifndef _T#define _T(x) x#endiftypedef struct in_addr IN_ADDR;typedef unsigned long       DWORD;typedef int                 BOOL;typedef unsigned char       BYTE;typedef unsigned short      WORD;typedef float               FLOAT;typedef FLOAT               *PFLOAT;typedef BOOL            *PBOOL;typedef BOOL             *LPBOOL;typedef BYTE            *PBYTE;typedef BYTE             *LPBYTE;typedef int             *PINT;typedef int              *LPINT;typedef WORD            *PWORD;typedef WORD             *LPWORD;typedef long             *LPLONG;typedef DWORD           *PDWORD;typedef DWORD            *LPDWORD;typedef void             *LPVOID;typedef int                 INT;typedef unsigned int        UINT;typedef unsigned int        *PUINT;typedef const char* LPCTSTR,*LPCSTR;typedef char* LPTSTR,*LPSTR;typedef void* RET_TYPE;inline int GetLastError(){return errno;}#define closesocket(x) close(x)#ifndef FALSE#define FALSE               0#endif#ifndef TRUE#define TRUE                1#endif#endif//MFC中已有CScoket,不太支持控制台,不支持多线程class CSockLx{protected:SOCKET m_hSocket;//核心成员变量public:operator SOCKET() const{return m_hSocket;}BOOL Create(UINT nSocketPort = 0, int nSocketType = SOCK_STREAM, LPCTSTR lpszSocketAddress = NULL);BOOL Accept(CSockLx& rConnectedSocket, LPTSTR szIP = NULL, UINT *nPort = NULL);BOOL Connect(LPCTSTR lpszHostAddress, UINT nHostPort);BOOL Listen(int nConnectionBacklog = 5){return !listen(m_hSocket, nConnectionBacklog);}int SendTo(const void* lpBuf, int nBufLen, UINT nHostPort, LPCTSTR lpszHostAddress = NULL, int nFlags = 0);int ReceiveFrom(void* lpBuf, int nBufLen, LPTSTR rSocketAddress, UINT& rSocketPort, int nFlags = 0);int Send(const void* lpBuf, int nBufLen, int nFlags = 0){return send(m_hSocket, (LPCSTR)lpBuf, nBufLen, nFlags);}int Receive(void* lpBuf, int nBufLen, int nFlags = 0){return recv(m_hSocket, (LPSTR)lpBuf, nBufLen, nFlags);}BOOL GetPeerName(LPTSTR rSocketAddress, UINT& rSocketPort);BOOL GetSockName(LPTSTR rSocketAddress, UINT& rSocketPort);void Close(){closesocket(m_hSocket);m_hSocket = INVALID_SOCKET;}#ifdef _UNICODEinline static void Pton(LPCTSTR sHostAddr, IN_ADDR &in){in.s_addr = inet_addr(_bstr_t(sHostAddr));}inline static void Ntop(IN_ADDR &in, LPTSTR sHostAddr){_tcscpy(sHostAddr, _bstr_t(inet_ntoa(in)));}#elseinline static void Pton(LPCTSTR sHostAddr, IN_ADDR &in){in.s_addr = inet_addr(sHostAddr);}inline static void Ntop(IN_ADDR &in, LPTSTR sHostAddr){strcpy(sHostAddr, inet_ntoa(in));}#endifCSockLx();virtual ~CSockLx();};

SockLx.cpp

// SockLx.cpp : Version 1.1(支持Unicode、支持VS2015和VC6编译环境)//Author:吕鑫老师封装类 (支持Linux开发)//吕鑫老师微博:http://t.qq.com/richmain 吕鑫老师微信:richmain//更多更好的是项目开发视频教程,请登录http://www.baojy.com////////////////////////////////////////////////////////////////////////#include "stdafx.h"#include "SockLx.h"#ifdef _WIN32#pragma comment (lib,"ws2_32.lib")#endifCSockLx::CSockLx(){#ifdef _WIN32WSAData wd;WSAStartup(0x0202, &wd);#endifm_hSocket = INVALID_SOCKET;}CSockLx::~CSockLx(){Close();}BOOL CSockLx::Create(UINT nSocketPort, int nSocketType, LPCTSTR lpszSocketAddress){//socket & bindm_hSocket = socket(AF_INET, nSocketType, 0);if (m_hSocket == INVALID_SOCKET){return FALSE;}sockaddr_in sa = { AF_INET,htons(nSocketPort) };if(lpszSocketAddress)Pton(lpszSocketAddress, sa.sin_addr);return !bind(m_hSocket, (sockaddr*)&sa, sizeof(sa));}BOOL CSockLx::Accept(CSockLx & socka, LPTSTR sIP, UINT * nPort){sockaddr_in sa = { AF_INET };socklen_t nLen = sizeof(sa);socka.m_hSocket = accept(m_hSocket, (sockaddr*)&sa, &nLen);if (INVALID_SOCKET == socka.m_hSocket)return FALSE;if (sIP)Ntop(sa.sin_addr, sIP);if (nPort)*nPort = htons(sa.sin_port);return TRUE;}BOOL CSockLx::Connect(LPCTSTR lpszHostAddress, UINT nHostPort){//封装也交隐藏sockaddr_in sa = { AF_INET,htons(nHostPort) };Pton(lpszHostAddress, sa.sin_addr);return !connect(m_hSocket, (sockaddr*)&sa, sizeof(sa));}int CSockLx::SendTo(const void * lpBuf, int nBufLen, UINT nHostPort, LPCTSTR lpszHostAddress, int nFlags){sockaddr_in sa = { AF_INET,htons(nHostPort) };Pton(lpszHostAddress, sa.sin_addr);sendto(m_hSocket, (const char*)lpBuf, nBufLen, 0, (sockaddr*)&sa, sizeof(sa));return 0;}int CSockLx::ReceiveFrom(void * lpBuf, int nBufLen, LPTSTR  rSocketAddress, UINT & rSocketPort, int nFlags){sockaddr_in sa = { AF_INET };socklen_t nLen = sizeof(sa);int nRet = recvfrom(m_hSocket, (char*)lpBuf, nBufLen, 0, (sockaddr*)&sa, &nLen);if (nRet <= 0)return nRet;rSocketPort = htons(sa.sin_port);if (rSocketAddress)Ntop(sa.sin_addr, rSocketAddress);return nRet;}BOOL CSockLx::GetPeerName(LPTSTR rSocketAddress, UINT & rSocketPort){sockaddr_in sa = { AF_INET };socklen_t nLen = sizeof(sa);if (getpeername(m_hSocket, (sockaddr*)&sa, &nLen) < 0)return FALSE;rSocketPort = htons(sa.sin_port);if (rSocketAddress)Ntop(sa.sin_addr, rSocketAddress);return TRUE;}BOOL CSockLx::GetSockName(LPTSTR rSocketAddress, UINT & rSocketPort){sockaddr_in sa = { AF_INET };socklen_t nLen = sizeof(sa);if (getsockname(m_hSocket, (sockaddr*)&sa, &nLen) < 0)return FALSE;rSocketPort = htons(sa.sin_port);if (rSocketAddress)Ntop(sa.sin_addr, rSocketAddress);return TRUE;}


服务端:Server.cpp

#include <iostream>#include "SockLx.h"//#include <WinSock2.h>using namespace std;enum{PORT=12345};#ifdef _WIN32  //windows下#include <WinSock2.h>typedef int socklen_t;#else      //Linux下#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>typedef unsigned int SOCKET;#define  INVALID_SOCKET (SOCKET)(~0)#define SOCKET_ERROR (-1)#endifint main(){CSockLx  sock;if(!sock.Create(PORT)){cout<<"create port error:"<<GetLastError()<<endl;return -1;}sock.Listen();char sIP[20];UINT nPort;CSockLx socka;char msg[2048];while(sock.Accept(socka,sIP,&nPort)){cout<<"User:"<<sIP<<"at port:"<<nPort<<" login"<<endl;int n=0;while(n=socka.Receive(msg,sizeof(msg))){msg[n]=0;cout<<msg<<endl;}cout<<"User:"<<sIP<<"at port:"<<nPort<<" exit"<<endl;}return 0;}


客户端:Client.cpp(注意:create()不带参数

#include <iostream>#include "SockLx.h"using namespace std;enum{PORT=12345};int main(){CSockLx sock;if(!sock.Create()){cout<<"create port error:"<<GetLastError()<<endl;return -1;}  if(!sock.Connect("127.0.0.1",PORT)){cout<<"connect error:"<<GetLastError()<<endl;return -1;}char msg[2048];while(true){cout<<"please input your message[#Exit]:";  cin>>msg;  if('#'==msg[0])  break;  sock.Send(msg,strlen(msg)); }return 0;}

测试:

先启动服务端,后启动客户端



原创粉丝点击