花了十个小时左右上网搜罗资料,写代码,改bug才写出了这么个程序,真是感慨对winsocket编程真是一窍不通啊。
先推荐本人认为比较不错的参考书:《Visual C++网络编程经典案例详解》《WinSock网络编程经络》,后者我在学校图书馆借到了,开篇就是我们第一个实验。
操作系统 win8
语言:c++
开放框架:QT
配置问题,很多同学会发现网上找的代码中有这么一段:
#pragma comment(lib, "ws2_32.lib")
这个倒入库文件的,在QT中的配置方法是在*.pro中加入:
LIBS += -lWs2_32
附上客户端代码
mainwindow.h代码:
1 #ifndef MAINWINDOW_H 2 #define MAINWINDOW_H 3 4 #define SERVER_ADDRESS "127.0.0.1" //服务器端IP地址 5 #define PORT 4000 //服务器的端口号 6 #define MSGSIZE 1024 //收发缓冲区的大小 7 8 9 #include <time.h> 10 #include <QMainWindow> 11 #include <winsock2.h> 12 #include <string> 13 namespace Ui { 14 class MainWindow; 15 } 16 17 class MainWindow : public QMainWindow 18 { 19 Q_OBJECT 20 21 private: 22 WSADATA wsaData;//定义WSADATA结构体对象 23 SOCKET ServerSocket;//s 24 SOCKADDR_IN ServerAddr; 25 //接受缓冲区 26 char RecvBuffer[MAX_PATH]; 27 //成功接收字节的个数 28 int Ret; 29 30 31 public: 32 33 explicit MainWindow(QWidget *parent = 0); 34 ~MainWindow(); 35 36 private slots: 37 void on_pushButton_clicked(); 38 39 void on_textBrowser_destroyed(); 40 41 private: 42 Ui::MainWindow *ui; 43 }; 44 45 #endif // MAINWINDOW_H
mainwindow.cpp代码
1 #include "mainwindow.h" 2 #include "ui_mainwindow.h" 3 #include <winsock2.h> 4 #include <iostream> 5 #include <stdlib.h> 6 using namespace std; 7 8 9 MainWindow::MainWindow(QWidget *parent) : 10 QMainWindow(parent), 11 ui(new Ui::MainWindow) 12 { 13 ui->setupUi(this); 14 } 15 16 MainWindow::~MainWindow() 17 { 18 delete ui; 19 } 20 21 void MainWindow::on_pushButton_clicked() 22 { 23 Ret = 0; 24 //Init Windows Socket 2.2 25 26 if(WSAStartup(MAKEWORD(2,2), &wsaData)!=0){ 27 cout<<"Init Windows Socket Failed::"<<GetLastError()<<endl; 28 29 } 30 31 // Create Socket 32 33 ServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 34 if ( ServerSocket == INVALID_SOCKET ) 35 { 36 cout<<"Create Socket Failed::"<<GetLastError()<<endl; 37 38 } 39 cout<<"Client starts"<<endl; 40 41 //AF_INET指明使用TCP/IP协议族; 42 //SOCK_STREAM, IPPROTO_TCP具体指明使用TCP协议 43 // 指明远程服务器的地址信息(端口号、IP地址等) 44 45 //memset(&ServerAddr, 0, sizeof(SOCKADDR_IN)); //先将保存地址的server置为全0 46 47 // 填写客户端地址信息 48 // 端口为PORT 49 // 服务器IP地址为本机ip,注意使用inet_addr将IP地址转换为网络格式 50 51 ServerAddr.sin_family = AF_INET; 52 ServerAddr.sin_port = htons(PORT); 53 ServerAddr.sin_addr.s_addr = inet_addr(SERVER_ADDRESS); 54 55 // 向服务器发出连接请求 56 //WinSock2:: 57 WINSOCK_API_LINKAGE::connect(ServerSocket, (SOCKADDR *) &ServerAddr, sizeof(ServerAddr)); 58 59 60 //send(ServerSocket, szMessage, strlen(szMessage), 0); //s指明用哪个连接发送; szMessage指明待发送数据的保存地址 ;strlen(szMessage)指明数据长度 61 memset(RecvBuffer, 0x00, sizeof(RecvBuffer)); 62 Ret = recv(ServerSocket, RecvBuffer, 16, 0); 63 if ( Ret == 0 || Ret == SOCKET_ERROR ) 64 { 65 cout<<"Server exist!"<<Ret<<endl; 66 } 67 cout<<"Server message:"<<RecvBuffer<<endl; 68 ui->label_2->setText(RecvBuffer); 69 70 71 72 73 // 新的连接建立后,就可以互相通信了,在这个简单的例子中,我们直接关闭连接, 74 // 并关闭监听Socket,然后退出应用程序 75 closesocket(ServerSocket); 76 WSACleanup(); 77 // 释放Windows Socket DLL的相关资源 78 79 80 81 }
下面是服务器端的:
#include <iostream> #include <windows.h> #include<sys/types.h> #include <winsock2.h> #include <stdlib.h> #include<ctime> #include <time.h> using namespace std; #define PORT 4000 #define IP_ADDRESS "127.0.0.1" #define MSGSIZE 1024 //收发缓冲区的大小 int main() { WSADATA Ws; SOCKET ServerSocket, CientSocket; struct sockaddr_in LocalAddr, ClientAddr; int Ret = 0; int AddrLen = 0; char tmpbuf[MSGSIZE]; //Init Windows Socket if ( WSAStartup(MAKEWORD(2,2), &Ws) != 0 ) { cout<<"Init Windows Socket Failed::"<<GetLastError()<<endl; return -1; } //Create Socket ServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if ( ServerSocket == INVALID_SOCKET ) { cout<<"Create Socket Failed::"<<GetLastError()<<endl; return -1; } cout<<"Server starts"<<endl; LocalAddr.sin_family = AF_INET; LocalAddr.sin_addr.s_addr = inet_addr(IP_ADDRESS); LocalAddr.sin_port = htons(PORT); memset(LocalAddr.sin_zero, 0x00, 8); //Bind Socket Ret = bind(ServerSocket, (struct sockaddr*)&LocalAddr, sizeof(LocalAddr)); if ( Ret != 0 ) { cout<<"Bind Socket Failed::"<<GetLastError()<<endl; return -1; } Ret = listen(ServerSocket, 10); if ( Ret != 0 ) { cout<<"listen Socket Failed::"<<GetLastError()<<endl; return -1; } cout<<"Server has been started"<<endl; while ( true ) { AddrLen = sizeof(ClientAddr); CientSocket = accept(ServerSocket, (struct sockaddr*)&ClientAddr, &AddrLen); if ( CientSocket == INVALID_SOCKET ) { cout<<"Accept Failed::"<<GetLastError()<<endl; break; } cout<<"Client connection::"<<inet_ntoa(ClientAddr.sin_addr)<<":"<<ClientAddr.sin_port<<endl; _strtime(tmpbuf); //_strdate(tmpbuf2); send(CientSocket, tmpbuf, strlen(tmpbuf), 0); //s指明用哪个连接发送; szMessage指明待发送数据的保存地址 ;strlen(szMessage)指明数据长度 } closesocket(ServerSocket); closesocket(CientSocket); WSACleanup(); return 0; }
程序运行界面: