标题:【菜鸡求助,谢谢大佬~】socket通信+线程(代码已贴,研究两天无果 T_T)
只看楼主
是心愿
Rank: 1
等 级:新手上路
帖 子:75
专家分:0
注 册:2016-6-22
结帖率:62.5%
已结贴  问题点数:40 回复次数:6 
【菜鸡求助,谢谢大佬~】socket通信+线程(代码已贴,研究两天无果 T_T)
client发data的方式不同导致结果不同。发数据的两种方式用感叹号标出了
想用循环达到方式2的效果,但是方式1的结果运行的不对。到底哪里错了呢?求指教~~~



client端:
程序代码:
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include "winsock2.h"
#pragma comment(lib,"ws2_32.lib")//引用库文件
using namespace std;

SOCKET sockClient[2];    //新!
char recvBuf[2][20];//新!
HANDLE hHandle;//
HANDLE existHandle[2];
int thread[2];

DWORD WINAPI Fun(LPVOID lp)
{
    int serverId = *(int*)(lp);
    DWORD hRes = 0;

    printf("enter Fun,serverId=%d \n", serverId);

    //用线程接收数据2

    if (recv(sockClient[serverId], recvBuf[serverId], sizeof(recvBuf), 0) <= 0) {
        printf("接受失败");

    }
    else {
        //printf("recvBuf[%d]=%s\n", serverId, recvBuf[serverId]);
        //closesocket(sockClient);

        //发送数据3
        char result1[] = "sat";
        char result2[] = "unsat";
        char buffs1[100] = "satStop";
        char buffs2[100] = "unsatGoon";
        if (strcmp(recvBuf[serverId], result1) == 0) {//sat

            printf("recvBuf[%d]=%s\n", serverId, recvBuf[serverId]);
            for (int i = 0;i < 2;i++) {
                if (i != serverId) {        //server1 sat 则给server2发stop
                    printf("here is sat,send to server%d to stop:%s\n", i, buffs1);
                    send(sockClient[i], buffs1, sizeof(buffs1), 0);                    //这里是i不是serverId了
                }
            }



            SetEvent(existHandle[serverId]);
        }
        else if (strcmp(recvBuf[serverId], result2) == 0) {//unsat

            printf("recvBuf[%d]=%s\n", serverId, recvBuf[serverId]);
            printf("server%d unsat\n", serverId);
            //printf("here is unsat send to server%d :%s\n", serverId, buffs2);
            //send(sockClient[serverId], buffs2, sizeof(buffs2), 0);
            SetEvent(existHandle[serverId]);
        }
        else {
            printf("绝望了\n");
        }


        //closesocket(sockClient[serverId]);



        return 0;
    }


    //closesocket(sockClient);
    //return 0;
}



int main()
{
    printf("This is client\n");
    //加载套接字
    WSADATA wsaData;
    char buff[1024];
    memset(buff, 0, sizeof(buff));

    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
    {
        printf("初始化Winsock失败");
        return 0;
    }


    SOCKADDR_IN addrSrv[2];
    //端口号 IP
    addrSrv[0].sin_family = AF_INET;
    addrSrv[0].sin_port = htons(8888);
    addrSrv[0].sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    //端口号 IP
    addrSrv[1].sin_family = AF_INET;
    addrSrv[1].sin_port = htons(2222);
    addrSrv[1].sin_addr.S_un.S_addr = inet_addr("127.0.0.1");


    //SOCKET sockClient[2];
    for (int i = 0;i < 2;i++) {

        //创建套接字
        sockClient[i] = socket(AF_INET, SOCK_STREAM, 0);
        if (SOCKET_ERROR == sockClient[0]) {
            printf("Socket() error:%d", WSAGetLastError());
            return 0;
        }

        //向服务器发出连接请求
        if (connect(sockClient[i], (struct  sockaddr*)&addrSrv[i], sizeof(addrSrv[i])) == INVALID_SOCKET) {
            printf("server1连接失败:%d", WSAGetLastError());
            return 0;
        }
    }

    /**
    //向server0,server1  发送数据1(方式1)!!!!
    char databuf[2][100];
    string str0 = "000000";
    string str1 = "111111";
    int length0 = str0.copy(databuf[0], 6);
    databuf[0][length0] = '\0';
    int length1 = str1.copy(databuf[1], 6);
    databuf[1][length1] = '\0';


    for (int i = 0;i < 2;i++) {

        send(sockClient[i], databuf[i], sizeof(databuf), 0);
        printf("send to server%d:%s\n", i, databuf[i]);
    }
    */

    

    /**
    //向server0,server1  发送数据1  (方式2)!!!!
    char databuf0[7] = "000000";
    char databuf1[7] = "111111";
    send(sockClient[0], databuf0, sizeof(databuf0), 0);
    send(sockClient[1], databuf1, sizeof(databuf1), 0);
    */

    printf("用线程接收数据\n ");
    //创建事件  
    for (int i = 0;i < 2;i++) {
        existHandle[i] = ::CreateEvent(NULL, FALSE, FALSE, NULL);
    }


    HANDLE hThread[8];
    //创建两线程
    int ID[2];
    for (int i = 0;i < 2;i++) {
        ID[i] = i;
        hThread[i] = CreateThread(NULL, 0, Fun, &ID[i], 0, NULL);

    }


    //等待全部线程运行结束
    int cn = 0;
    while (true)
    {
        printf("没wait到呢\n ");
        DWORD hr = WaitForMultipleObjects((DWORD)2, existHandle, false, INFINITE);
        if (hr == WAIT_FAILED) {
            break;
            printf("hr == WAIT_FAILED\n ");
        }
        cn++;
        printf("1\n ");
        if (cn >= 2)    //两个线程都执行完毕
        {
            printf("主线程要结束了\n ");
            break;
        }
    }
    //关闭套接字
    //closesocket(sockClient[0]);
    //closesocket(sockClient[1]);
    WSACleanup();//释放初始化Ws2_32.dll所分配的资源。
    system("pause");//让屏幕暂留
    return 0;
}



server1
程序代码:
#include <iostream>
#include <stdlib.h>
#include "project.h"
#include <stdio.h>
#include "winsock2.h"
#include<cstdlib>
#pragma comment(lib,"ws2_32.lib")//引用库文件
using namespace std;


char recvBuf1[49];
short buff[49];
SOCKET sockConn;
HANDLE hEvent;


DWORD WINAPI Fun(LPVOID lpParamter)
{
    char buff2[100];
    char result[] = "satStop";
    memset(buff2, 0, sizeof(buff2));
    if (recv(sockConn, buff2, sizeof(buff2), 0) < 0) {
        printf("Receive fail\n");
    }
    else {
        printf("Receive form client success:%s\n", buff2);
        if (strcmp(buff2, result) == 0) {
            SetEvent(hEvent);
        }

        return 0;
    }

}



int main()
{
    printf("server0 ready\n");
    WSADATA wsaData;
    int port = 8888;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
    {
        printf("初始化失败");
        return 0;
    }

    //创建用于监听的套接字,即服务端的套接字
    SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);
    SOCKADDR_IN addrSrv;
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(port);
    addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    //bind
    int retVal = bind(sockSrv, (LPSOCKADDR)&addrSrv, sizeof(SOCKADDR_IN));
    if (retVal == SOCKET_ERROR) {
        printf("连接失败:%d\n", WSAGetLastError());
        return 0;
    }
    //listen
    if (listen(sockSrv, 10) == SOCKET_ERROR) {
        printf("监听失败:%d", WSAGetLastError());
        return 0;
    }

    SOCKADDR_IN addrClient;
    int len = sizeof(SOCKADDR);

    while (1)
    {
        //等待客户请求到来
        sockConn = accept(sockSrv, (SOCKADDR *)&addrClient, &len);
        if (sockConn == SOCKET_ERROR) {
            printf("等待请求失败:%d", WSAGetLastError());
            break;
        }

        printf("客户端的IP是:[%s]\n", inet_ntoa(addrClient.sin_addr));



        //接收confirm
        recv(sockConn, recvBuf1, sizeof(recvBuf1), 0);
        cout << recvBuf1;
        printf("char buff end\n");

        //将buf转为short类型
        for (int j = 0;j < 48;j++) {
            buff[j] = recvBuf1[j] - '0';
            //cout << "Shh " << buffs[i][j];
            printf("buff][%d] = %d", j, buff[j]);
            printf("\n short buf end\n");
        }

        //将数据赋值给confirm
        bool isTrue = ConfirmedVar(buff);
        if (isTrue == 0) {
            printf("has confirmed");
            //printf(ConfirmedVariableAllUnitsAssignment[][]);
        }


        //发送数据2

        char sendbuf1[] = "unsat";
        int Send = send(sockConn, sendbuf1, sizeof(sendbuf1), 0);
        if (Send == SOCKET_ERROR) {
            printf("发送失败");
            break;
        }
        else {
            printf("unsat发送成功\n");
        }


        hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); //使用手动重置为无信号状态,初始化时有信号状态

        int id[2];
        HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Fun, &id[0], 0, NULL);

        int cn2 = 0;
        while (true)
        {
            printf("没wait到呢\n ");
            DWORD hr = WaitForSingleObject(hEvent, INFINITE);
            if (hr == WAIT_FAILED) {
                break;
                printf("hr == WAIT_FAILED\n ");
            }
            cn2++;
            printf("cn2=%d\n ", cn2);
            if (cn2 >= 1)    //两个线程都执行完毕
            {
                printf("子线程setEvent了,主线程要结束了\n ");
                break;
            }
        }

        closesocket(sockConn);

    }//while

    closesocket(sockSrv);
    WSACleanup();
    system("pause");
    return 0;
}



server2
程序代码:
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include "winsock2.h"
#include<cstdlib>
#pragma comment(lib,"ws2_32.lib")//引用库文件
using namespace std;



char recvBuf[100];
SOCKET sockConn;
HANDLE hEvent;



DWORD WINAPI Fun(LPVOID lpParamter)
{
    char buff2[100];
    char result[] = "satStop";
    memset(buff2, 0, sizeof(buff2));
    if (recv(sockConn, buff2, sizeof(buff2), 0) < 0) {
        printf("Receive fail\n");
    }
    else {
        printf("Receive form client success:%s\n", buff2);
        if (strcmp(buff2, result) == 0) {
            SetEvent(hEvent);
        }

        return 0;
    }
    return 0;
}



int main()
{
    printf("This is server 1\n");
    WSADATA wsaData;
    int port = 2222;//端口号
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
    {
        printf("初始化失败");
        return 0;
    }

    //创建用于监听的套接字,即服务端的套接字
    SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);

    SOCKADDR_IN addrSrv;
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(port); //1024以上的端口号

    addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);

    int retVal = bind(sockSrv, (LPSOCKADDR)&addrSrv, sizeof(SOCKADDR_IN));
    if (retVal == SOCKET_ERROR) {
        printf("连接失败:%d\n", WSAGetLastError());
        return 0;
    }

    if (listen(sockSrv, 10) == SOCKET_ERROR) {
        printf("监听失败:%d", WSAGetLastError());
        return 0;
    }

    SOCKADDR_IN addrClient;
    int len = sizeof(SOCKADDR);

    while (1)
    {
        //等待客户请求到来
        sockConn = accept(sockSrv, (SOCKADDR *)&addrClient, &len);
        if (sockConn == SOCKET_ERROR) {
            printf("等待请求失败:%d", WSAGetLastError());
            break;
        }

        
        //接收数据1
        recv(sockConn, recvBuf, sizeof(recvBuf), 0);
        printf("Receive form client:%s\n", recvBuf);
        

        //发送数据2
        char sendbuf1[] = "unsat";
        int Send = send(sockConn, sendbuf1, sizeof(sendbuf1), 0);
        if (Send == SOCKET_ERROR) {
            printf("发送失败");
            break;
        }



        hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); //使用手动重置为无信号状态,初始化时有信号状态

        int id[2];
        HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Fun, &id[0], 0, NULL);

        int cn2 = 0;
        while (true)
        {
            printf("没wait到呢\n ");
            DWORD hr = WaitForSingleObject(hEvent, INFINITE);
            if (hr == WAIT_FAILED) {
                break;
                printf("hr == WAIT_FAILED\n ");
            }
            cn2++;
            printf("cn2=%d\n ", cn2);
            if (cn2 >= 1)    //两个线程都执行完毕
            {
                printf("子线程setEvent了,主线程要结束了\n ");
                break;
            }
        }

    }

    closesocket(sockConn);
    closesocket(sockSrv);
    WSACleanup();
    system("pause");
    return 0;
} 
搜索更多相关主题的帖子: char int printf sizeof return 
2018-08-07 17:23
是心愿
Rank: 1
等 级:新手上路
帖 子:75
专家分:0
注 册:2016-6-22
得分:0 
就lient发数据用的是方式1时,第一个server会莫名其妙的收到111111,但是111111我只给第二个server发了呀。不用循环就没有这种问题,但我真的好想用循环...
2018-08-07 17:33
root2008
Rank: 2
等 级:论坛游民
帖 子:35
专家分:31
注 册:2018-8-7
得分:20 
不行的时候就放弃掉   
2018-08-11 17:21
root2008
Rank: 2
等 级:论坛游民
帖 子:35
专家分:31
注 册:2018-8-7
得分:0 
话说你有服务器?        
2018-08-11 17:22
Jonny0201
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:贵宾
威 望:52
帖 子:488
专家分:2603
注 册:2016-11-7
得分:20 
回复 4楼 root2008
你这个算是什么回复?
不知道可以不回复
什么叫实在不行就放弃?
2018-08-11 20:23
wjjzzl
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2018-9-21
得分:0 
一个个分解开来试,我一般遇到找不出来的错误都是这样做的,每一个功能单独提出来试,试成功了再组合起来;还有用一个输出的语句,插进去取运行,语句里面带入要观察的变量,看运行的时候这个变量正不正常,多试几次,看到哪里不正常。
2018-09-21 09:15
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:0 
懒得创建工程,就用肉眼看吧

if (SOCKET_ERROR == sockClient[0]) { 应该是 if (SOCKET_ERROR == sockClient[i]) {
send(sockClient[i], databuf[i], sizeof(databuf), 0); 应该是 send(sockClient[i], databuf[i], 6, 0);
2018-09-21 10:01



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-489081-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.036544 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved