至于为什么用vc6.0,我用的是xp系统,没钱
有错误请指出,本人业余的(所写的代码,尽量注释清楚)通过vc6.0的直接复制粘贴即可
(代码来源于网络,
仅供学习交流,严禁用于商业用途
)
本人参考的大神的代码,这个代码写的比较简单易懂!推荐大家先去看看(看完再看我的,容易理解)
http://blog.csdn.net/lcytrl/article/details/7896073
下面代码复杂了点,我对别人的代码是进行了解释,能看就看看吧!
服务器端
////服务器端代码 sever.cpp ///一、初始化套接字 ///二、创建套接字 ///三、绑定 ///四、侦听 ///五、接收 ///六、发送 ///七、销毁连接 //// #include#include //#include #pragma comment(lib,"WS2_32.lib") using namespace std; #define SER_PORT 5000 //预定义端口定义 #define SER_IP "127.0.0.1" //预定义的IP 此IP是测试专用自发自收IP,详情百度哈,当然,也可以转发测试 DWORD WINAPI ThreadProcessor(LPVOID lpParameter); //接收数据的线程函数 //后面笔记会讲到(不用理解)fd_set fdRead = { 0}; int main() { SOCKET sever; ///定义套接字 描述一个数值,跟定义int sever差不多;注意区别 SOCKET client; //socket 网络中,只能用socket定义一些值 char buf[1024]; SOCKADDR_IN ser_addr; //服务器地址信息 (指定ser_addr) (至于用法,我大概知道什么意思) //(不太懂的话,好好学习结构体,和百度) SOCKADDR_IN cli_addr; //客户端地址信息 //HANDLE hnd; int ret; //用于保存函数返回值 WORD wVersionRequested; // ↓启动版本 WSADATA wsaData; int cliAddrLen; // ↓2.2版本(至于有什么区别我也不知道,大家百度) wVersionRequested=MAKEWORD(2,2); if(WSAStartup(wVersionRequested,&wsaData)!=0) // ↓ { cout << "初始化失败!\n"; // ↑大致就是启动函数 return 1; } // ↑ ser_addr.sin_family = AF_INET; ser_addr.sin_addr.S_un.S_addr = inet_addr(SER_IP); //输入IP地址 ser_addr.sin_port = htons(SER_PORT); //输入端口地址 memset(ser_addr.sin_zero,0,8); ///创建套接字 sever = socket(AF_INET,SOCK_STREAM,0); //如果绑定ip和端口成功,应该返回一个值// // if (sever == INVALID_SOCKET) //一般很难创建失败,除非前面写程序有错误,改ip和端口 { cout << "创建套接字失败!\n"; //直接在预定义改,比较方便 return 1; } //绑定 if(bind(sever, (SOCKADDR *)&ser_addr, sizeof(SOCKADDR)) != 0) //sizeof()函数 取出地址结构长度 { cout << "绑定失败!\n"; return 1; } else { cout << "服务器端已成功启动......\n\n"; } /****下面是绑定的结构图 int bind ( SOCKET s, //要绑定的套接字 const struct sockaddr FAR* name, //指定了该套接字的本地地址信息 int namelen //该地址结构的长度);****///到此上面所有的步骤完成,代表了开启了服务器、、有什么不动可以查看我的参考网址 while (1) //服务器端继续搜索新的连接 { //侦听 if (int i = listen(sever,6) != 0) //一般防火墙和某些软件冲突 //一般不会影响的侦听 { cout << "侦听失败: " << WSAGetLastError() < <= 0 ) //阻塞控制 读取数据才向下 { continue; //结束循环//这里继续向下 } if (ret>0) { if (FD_ISSET(client,&fdRead)) //client in fdRead { int RecvBytes=0; do //循环读取数据,直到缓冲区中的数据读完- 这个可能有错误 { //接收数据 RecvBytes = recv(client,buf,sizeof(buf),0); //读取数据放到RecvBytes if (RecvBytes==SOCKET_ERROR || RecvBytes == 0) //查询,是否一直在连接 { cout << "数据接收失败或客户端已经断开!\n"; bAvail = false; break; } //c语言里面字符串结束符'\0'的值就是0,所以buf[buf_len] = 0; 通buf[buf_len] = '\0'; buf[RecvBytes] = 0; //给数据串加上结束符 //打印收到数据 cout << "收到" << RecvBytes <<" bytes 数据: " << buf < 0); } } FD_ZERO(&fdRead); }//while closesocket(client); }//while cout << "end\n"; Sleep(5000); FD_CLR(client,&fdRead); closesocket(sever); WSACleanup(); return 0; }
客服端
#include#include #include #pragma comment(lib,"WS2_32.lib") using namespace std; #define DES_IP "122.114.122.174" #define DES_PORT 38111 //#define DES_IP "127.0.0.1" //#define DES_PORT 5000 int main() { SOCKET sock; char buf[1024]; //发送的字串 SOCKADDR_IN ser_addr; WSADATA wsaData; WORD wVersionRequired; wVersionRequired = MAKEWORD(2,2); if (WSAStartup(wVersionRequired,&wsaData)!=0) { cout< < > buf; if(strcmp(buf,"exit") ==0 ) break; SentBytes = send( sock,buf, strlen(buf), 0 ); if (SentBytes == SOCKET_ERROR) ///发送失败 { cout << "发送数据失败!\n\n"; break; } // else //发送成功 // { // cout << buf <
这里说明以下,只是作为理解讲解,主要还是看上面那个网站
下面是运行效果(BUG只能接受到了,才能发送,如果没有接受到,就发送不了,但要发送的数据会被保存在缓冲中,等待着下次收到发送时,一并打出)(BUG都是程序不完善引起)