2017-05-14 35 views
0

我在法國學習,對不起我的英語,我有一個項目要實現,我用一個客戶端TCP編程一個industreille機器,我必須發送傳感器信息在tcp服務器上, 我想知道如何使用線程我可以在同一個程序上同時運行客戶端和服務器,我不是一個好程序員請幫我...在同一個程序中啓動一個TCP客戶端和服務器(在c)

客戶端:

/************* BIBIOTHEQUE *********************/ 
 
#include <winsock2.h> 
 
#include <windows.h> 
 
#include <stdio.h> 
 
#include <conio.h> 
 
#include <unistd.h> 
 

 
/*************  SORTIES ***********************/ 
 
#define EJECTION_PIECE     0x01 // bit 0 
 
#define ASPIRATION_ONA     0x02 // bit 1 
 
#define EXPULSION_VENTOUSE    0x04 // bit 2 
 
#define BRAS_POSITION_MAGASINA   0x08 // bit 3 
 
#define BRAS_POSITION_MODULE_CONTROLEA 0x10 // bit 4 0001 1000 0X18 
 

 
/*************  ENTREES ************************/ 
 
#define NON_DISPONIBLE    0x01 // bit 0 1 1 
 
#define EJECTION_PIECE_RETRACTE  0x02 // bit 1 1 0 
 
#define EJECTION_PIECE_AVANCE   0x04 // bit 2 0 1 
 
#define ASPIRATION_ON     0x08 // bit 3 0 0 
 
#define BRAS_POSITION_MAGASIN   0x10 // bit 4 0 0 
 
#define BRAS_POSITION_MODULE_CONTROLE 0x20 // bit 5 0 0 
 
#define RESERVE_PIECE_VIDE   0x40 // bit 6 1 0 
 
#define ASPIRATION_OFF    0x80 // bit 7 1 1 
 

 
/*************  PORT & IP ************************/ 
 
#define PORT1 4200 
 
#define PORT2 4200 
 
#define IP2 "172.16.1.24" //serveur Tcp 
 

 
SOCKADDR_IN info_Trame; 
 
SOCKADDR_IN envoie_donnee_serveur; 
 

 
/*int nombre_de_caractere; 
 
int nombre_de_caractere_recu ; 
 
int nombre_de_caractere_recu_Capteur; 
 
int nombre_caractere_recu_serveur; 
 
int nombre_de_caractere_envoi_serveur; 
 
int nombre_de_caractere_Capteur; 
 

 
char buffer1[50]; 
 
//char buffer2[50]; 
 
char buffer3[50]; 
 
*/ 
 

 
SOCKET configurationTCP(char ip[], uint16_t port) 
 
{ 
 
    SOCKET id_de_la_socket; 
 

 
    WSADATA initialisation_win32; /// Variable pour récupérer la structure d'information sur l'initialisation 
 
    int erreur; 
 

 
    printf("programme client tcp\n"); 
 

 
    erreur=WSAStartup(MAKEWORD(2,2),&initialisation_win32); 
 
    if (erreur!=0) 
 
     printf("\n impossible d'initialiser Winsock : %d %d",erreur,WSAGetLastError()); 
 
    else 
 
     printf("\n WSAStartup réussi "); 
 

 
    // Ouverture d'une Socket 
 
    //id_de_la_socket=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP); /// Ouverture d'une Socket 
 
    id_de_la_socket=socket(AF_INET,SOCK_STREAM,0); 
 
    printf("id socket =%d\n",id_de_la_socket); 
 
    if (id_de_la_socket==INVALID_SOCKET) 
 
     printf("\n impossible de creer la socket : %d ",WSAGetLastError()); 
 
    else 
 
     printf("\n socket valider \n "); 
 

 

 
    // OUVERTURE DE SESSION TCP 
 
    info_Trame.sin_family=AF_INET; 
 
    info_Trame.sin_addr.s_addr=inet_addr(ip); 
 
    info_Trame.sin_port = htons(port); 
 
    erreur=connect(id_de_la_socket,(struct sockaddr*)&info_Trame,sizeof(info_Trame)); 
 
    if (erreur!=0) 
 
     printf("\n impossible d'ouvrir la session TCP : %d %d",erreur,WSAGetLastError()); 
 
    else 
 
     printf("\n OUVERTURE DE SESSION TCP : OK \n "); 
 

 
    return id_de_la_socket; 
 
} 
 

 

 

 
void fermetureTCP(SOCKET id_de_la_socket) 
 
{ 
 
    int erreur; 
 

 
    erreur=shutdown(id_de_la_socket,2); // 2 signifie socket d'émission et d'écoute 
 
    if (erreur!=0) 
 
     printf("\n Desole, je ne peux pas fermer la session TCP du a l'erreur : %d %d",erreur,WSAGetLastError()); 
 
    else 
 
     printf("\n Session TCP : Arreter \n "); 
 

 
    // FERMETURE DE LA SOCKET 
 
    erreur=closesocket(id_de_la_socket); 
 
    if (erreur!=0) 
 
     printf("\n Desole, je ne peux pas arreter la socket machine du a l'erreur : %d %d",erreur,WSAGetLastError()); 
 
    else 
 
     printf("\n Socket machin : Arreter \n"); 
 

 
    // Fermeture de WSAStartup 
 
    erreur=WSACleanup(); 
 
    if (erreur!=0) 
 
     printf("\n Desole, je ne peux pas liberer winsock du a l'erreur : %d %d",erreur,WSAGetLastError()); 
 
    else 
 
     printf("\n WSACleanup : OK \n"); 
 
    getchar(); 
 
} 
 

 

 
void ecritureModbus(SOCKET id_de_la_socket, unsigned char donnees1, unsigned char donnees2) 
 
{ 
 
    unsigned char trameModbus[12]= {0x6c ,0x1f, 0x00, 0x00, 0x00, 0x06, 0xff, 0x06,0x9c,0x42}; 
 
    unsigned char buffer[50]; 
 
    int nombre_de_caractere_recu, i; 
 
    int nombre_de_caractere; 
 

 
    trameModbus[10] = donnees1; 
 
    trameModbus[11] = donnees2; 
 

 
    nombre_de_caractere=send(id_de_la_socket,(char *)trameModbus,12,0); 
 

 
    if (nombre_de_caractere==SOCKET_ERROR) 
 
     printf("\n Desole, je n'ai pas envoyer les donnees du a l'erreur : %d",WSAGetLastError()); 
 
    else 
 
     printf("\n send trame  : OK"); 
 

 
    nombre_de_caractere_recu=recv(id_de_la_socket,(char *)buffer,12,0); 
 
    if (nombre_de_caractere_recu==SOCKET_ERROR) 
 
     printf("\n Desole, je n'ai pas recu de donnee de la trame "); 
 
    else 
 
    { 
 
     printf("\nTrame modbus reçue : "); 
 
     for(i=0; i< nombre_de_caractere_recu; i++) 
 
     { 
 
      printf("%x ",buffer[i]); 
 
     } 
 
     printf("\n"); 
 
    } 
 
} 
 

 
unsigned char lectureModbus(SOCKET id_de_la_socket, unsigned char donnees1, unsigned char donnees2) //tram modbus capteur 
 
{ 
 
    unsigned char trameModBus_capteur[12]= {0x50, 0xa2, 0x00, 0x00, 0x00, 0x06, 0xff, 0x03, 0xb1, 0x53}; 
 
    unsigned char buffer[50]; 
 
    int nombre_de_caractere_recu_capteur, i; 
 
    int nombre_de_caractere_capteur; 
 
    trameModBus_capteur[10] = donnees1; 
 
    trameModBus_capteur[11] = donnees2; 
 

 
    nombre_de_caractere_capteur=send(id_de_la_socket,(char *)trameModBus_capteur,12,0); 
 
    if (nombre_de_caractere_capteur==SOCKET_ERROR) 
 
     printf("\nFonction modbus 3 : probleme envoi trame : %d",WSAGetLastError()); 
 
    else 
 
     printf("\nsend trame  : OK\n"); 
 

 
    nombre_de_caractere_recu_capteur=recv(id_de_la_socket,(char *)buffer,12,0); 
 
    if (nombre_de_caractere_recu_capteur==SOCKET_ERROR) 
 
     printf("\nFonction modbus 3 : probleme reception trame"); 
 
    else 
 
    { 
 
     printf("\nTrame modbus reçue de la fonction 3 : "); 
 
     for(i=0; i< nombre_de_caractere_recu_capteur; i++) 
 
     { 
 
      printf("%x ",buffer[i]); 
 
     } 
 
     printf("\n"); 
 
    } 
 
    return buffer[10]; 
 
} 
 

 
unsigned char mettreBrasEnRepos(SOCKET id_de_la_socket, unsigned char sorties) 
 
{ 
 

 
    unsigned char entrees; 
 
    entrees=lectureModbus(id_de_la_socket,0x00, 0x01); 
 
    printf("\n entrees = %x\n",entrees); 
 
    if((entrees & BRAS_POSITION_MAGASIN) == BRAS_POSITION_MAGASIN) 
 
    { 
 
     sorties=BRAS_POSITION_MODULE_CONTROLEA^sorties; 
 
     ecritureModbus(id_de_la_socket,(unsigned char)0x0, sorties); 
 
     Sleep(1855); 
 
     sorties=(~BRAS_POSITION_MODULE_CONTROLEA)&sorties; 
 
     ecritureModbus(id_de_la_socket,(unsigned char)0x0, sorties); 
 
    } 
 
    if((entrees & BRAS_POSITION_MODULE_CONTROLE) == BRAS_POSITION_MODULE_CONTROLE) 
 
    { 
 
     sorties=BRAS_POSITION_MAGASINA^sorties; 
 
     ecritureModbus(id_de_la_socket,(unsigned char)0x0, sorties); 
 
     Sleep(1860); 
 
     sorties=(~BRAS_POSITION_MAGASINA)&sorties; 
 
     ecritureModbus(id_de_la_socket,(unsigned char)0x0, sorties); 
 
    } 
 
    return sorties; 
 
} 
 

 

 

 

 
unsigned char test_reservoir_plus_action(SOCKET id_de_la_socket, unsigned char sorties) 
 
{ 
 
    unsigned char entrees; 
 
    int vide; 
 

 

 
    entrees=RESERVE_PIECE_VIDE; 
 
    if( (entrees & RESERVE_PIECE_VIDE) == RESERVE_PIECE_VIDE) 
 
    { 
 

 

 
    } 
 

 
    // Boucle d'attente reserve vide 
 
    vide=1; 
 

 

 
    do 
 
    { 
 
     entrees=lectureModbus(id_de_la_socket,0x00, 0x01); 
 
     printf("entrees = %x\n",entrees); 
 
     if((entrees & RESERVE_PIECE_VIDE) == RESERVE_PIECE_VIDE) 
 
     { 
 
      printf("Reserve vide !!!\n"); 
 
     } 
 
     else 
 
     { 
 
      vide=0; 
 
     } 
 

 
    } 
 
    while(vide == 1); 
 
    printf("sorties = %X\n",sorties); 
 
    sorties=EJECTION_PIECE^sorties; 
 
    ecritureModbus(id_de_la_socket,(unsigned char)0x00, sorties); /// Probleme 
 

 
    return sorties; 
 
} 
 

 

 
unsigned char test_brasgauche_plus_action(SOCKET id_de_la_socket, unsigned char sorties) 
 
{ 
 
    unsigned char entrees; 
 

 

 

 
    entrees=lectureModbus(id_de_la_socket,0x00, 0x01); 
 
    printf("\n entrees = %x\n",entrees); 
 
    if((entrees & BRAS_POSITION_MODULE_CONTROLE) == BRAS_POSITION_MODULE_CONTROLE) 
 
    { 
 
     printf("Bras n'est pas a droit \n"); 
 
    } 
 
    else 
 
    { 
 

 
     sorties=BRAS_POSITION_MAGASINA^sorties; 
 
     ecritureModbus(id_de_la_socket,(unsigned char)0x0, sorties); 
 
    } 
 
    Sleep(3000); 
 

 
    return sorties; 
 
} 
 

 

 
Serveur : 
 

 

 
unsigned char test_aspirationon_plus_action(SOCKET id_de_la_socket, unsigned char sorties) 
 
{ 
 

 
    unsigned char entrees; 
 

 
    entrees=lectureModbus(id_de_la_socket,0x00, 0x01); 
 
    printf("\n entrees = %x\n",entrees); 
 
    if((entrees & ASPIRATION_ON) == ASPIRATION_ON) 
 
    { 
 
     printf("Bras n'est pas a droit \n"); 
 
    } 
 
    else 
 
    { 
 
     sorties=ASPIRATION_ONA^sorties; 
 
     ecritureModbus(id_de_la_socket,(unsigned char)0x0, sorties); 
 
    } 
 

 
    return sorties; 
 
} 
 

 

 
unsigned char test_brasdroite_plus_action(SOCKET id_de_la_socket, unsigned char sorties) 
 
{ 
 

 
    unsigned char entrees; 
 

 
    entrees=lectureModbus(id_de_la_socket,0x00, 0x01); 
 
    printf("\n entrees = %x\n",entrees); 
 
    if((entrees & BRAS_POSITION_MODULE_CONTROLE) == BRAS_POSITION_MODULE_CONTROLE) 
 
    { 
 
     printf("Bras n'est pas a droit \n"); 
 
    } 
 
    else 
 
    { 
 

 
     sorties=BRAS_POSITION_MAGASINA^sorties; 
 
     ecritureModbus(id_de_la_socket,(unsigned char)0x0, sorties); 
 
    } 
 
    Sleep(3000); 
 

 

 
    return sorties; 
 
} 
 

 

 
unsigned char test_aspiratiooff_plus_action(SOCKET id_de_la_socket, unsigned char sorties) 
 
{ 
 

 
    unsigned char entrees; 
 

 
    entrees=lectureModbus(id_de_la_socket,0x00, 0x01); 
 
    printf("\n entrees = %x\n",entrees); 
 
    if((entrees & ASPIRATION_OFF) == ASPIRATION_OFF) 
 
    { 
 
     printf("Bras n'est pas a droit \n"); 
 
    } 
 
    else 
 
    { 
 
     sorties=EXPULSION_VENTOUSE^sorties; 
 
     ecritureModbus(id_de_la_socket,(unsigned char)0x0, sorties); 
 
    } 
 

 
    return sorties; 
 
} 
 

 

 

 
int main() 
 
{ 
 
    unsigned char sorties=0x00; 
 
    unsigned char sorties1=0x01; 
 
    unsigned char entrees; 
 
    unsigned char car='a'; 
 
    int nombre_caractere_recu_serveur; 
 
    int nombre_de_caractere_envoi_serveur; 
 
    int vide,gauche,droite,retracter,etape; 
 

 
    SOCKET id_de_la_socket=configurationTCP("192.168.10.244",502); 
 
    SOCKET id_de_la_socket2=configurationTCP("172.16.1.24",4200); 
 

 

 
    sorties=mettreBrasEnRepos(id_de_la_socket,sorties); 
 
    Sleep(3000); 
 

 
    sorties=test_reservoir_plus_action(id_de_la_socket,sorties); 
 

 
    Sleep(3000); 
 
    sorties=test_brasgauche_plus_action(id_de_la_socket,sorties); 
 
    Sleep(3000); 
 
    sorties=test_aspirationon_plus_action(id_de_la_socket,sorties); 
 
    Sleep(3000); 
 
    sorties=test_brasdroite_plus_action(id_de_la_socket,sorties); 
 
    Sleep(3000); 
 
    sorties=test_aspiratiooff_plus_action(id_de_la_socket,sorties); 
 

 

 
    /* 
 
     //lectureModbus(id_de_la_socket,0x00, 0x01); 
 
     printf("sorties =%x\n",car); 
 
     // nombre_de_caractere_envoi_serveur=send(id_de_la_socket2,(char *)&car,1,0); // partie envois supoervisuer ou mon serveur tcp 
 
     nombre_de_caractere_envoi_serveur=send(id_de_la_socket2,(char *)"sortie=X",9,0); // partie envois supoervisuer ou mon serveur tcp 
 
     if (nombre_de_caractere_envoi_serveur==SOCKET_ERROR) 
 

 
      printf("\n Desole, je n'ai pas envoyer les donnees du a l'erreur : %d",WSAGetLastError()); 
 
     else 
 
     { 
 

 
      printf("\n send donnee Serveur : OK : %d",nombre_de_caractere_envoi_serveur); 
 

 
     } 
 
    */ 
 

 
    fermetureTCP(id_de_la_socket); 
 
    fermetureTCP(id_de_la_socket2); 
 
    return 0; 
 
}

#include <stdio.h> 
 
#include <clib.h> 
 

 
#define PORT_ECHO      7 /*well known echo port*/ 
 
#define TCPECHOBUF_SERVER_RECVSIZE 1024 
 

 

 
static char recvbuf[TCPECHOBUF_SERVER_RECVSIZE]; 
 
static char ClientIP[INET_ADDRSTRLEN]; 
 

 

 

 
/****************************************************************************** 
 
* main()                  * 
 
******************************************************************************/ 
 
int main(void) 
 
{ 
 
    struct sockaddr_in addr; 
 
    struct sockaddr_in claddr; 
 

 
    int sd; 
 
    int asd; 
 
    int established = 0; 
 
    int i; 
 
    int retval; 
 
    int error; 
 

 
    printf("\r\nTCPserver, listening on port %d\r\n",PORT_ECHO); 
 

 
    sd = opensocket(SOCK_STREAM, &error); 
 
    if(sd == API_ERROR) 
 
    { 
 
     printf("\r\nSocket open failed: %d",error); 
 
     return -1; 
 
    } 
 

 
    addr.sin_family  = PF_INET; 
 
    addr.sin_port  = htons(PORT_ECHO); 
 
    addr.sin_addr.s_addr = 0L; 
 

 
    retval = bind(sd, (const struct sockaddr *)&addr, &error); 
 
    if(retval == API_ERROR) 
 
    { 
 
     printf("\r\nTCPserver: Socket bind failed: %d",error); 
 
     return -1; 
 
    } 
 

 

 
    /********************************************************************** 
 
    *Listen for connections            * 
 
    **********************************************************************/ 
 
    printf("\r\nTCPserver: Listening for connection"); 
 
    retval = listen(sd, 1, &error); 
 
    if(retval == API_ERROR) 
 
    { 
 
     printf("\r\nTCPserver: Socket listen failed: %d",error); 
 
     return -1; 
 
    } 
 
    while(1) 
 
    { 
 
    /********************************************************************** 
 
    *accept, establish a connection          * 
 
    **********************************************************************/ 
 
    claddr.sin_family  = PF_INET; 
 
    claddr.sin_port  = 0; 
 
    claddr.sin_addr.s_addr = 0L; 
 

 
    retval = accept(sd, (struct sockaddr *)&claddr, &error); 
 
    if(retval == API_ERROR) 
 
    { 
 
     printf("\r\nTCPserver: Socket accept failed: %d",error); 
 
     return -1; 
 
    } 
 

 
    //save the new socket descriptor 
 
    asd = retval; 
 
    established = 1; 
 

 
    InetToAscii((unsigned long *) &claddr.sin_addr.s_addr, (char *) ClientIP); 
 

 
    printf("\r\nTCPserver: Connected with %s , Port %u\r\n",ClientIP, htons(claddr.sin_port)); 
 
    while(established) 
 
    { 
 
printf("1"); 
 
     /******************************************************************** 
 
     *Wait for incoming data from the client        * 
 
     ********************************************************************/ 
 
     do 
 
     { 
 
printf("2"); 
 
      retval = recv(asd, (char *)recvbuf, TCPECHOBUF_SERVER_RECVSIZE, 
 
      MSG_TIMEOUT, 20000L, &error); 
 
      printf("retval=%d ",retval); 
 
      printf("car=%c ",recvbuf[0]); 
 
      recvbuf[0]=recvbuf[0]+1; 
 
      if(retval == API_ERROR) 
 
      { 
 
      printf("\r\nTCPserver: Receive error %d",error); 
 
      established = 0; 
 
      break; 
 
      } 
 
      else 
 
      { 
 
      if(retval > 0) //data received 
 
      { 
 
\t \t \t \t printf("\r\nTCPserver: Received data\r\n"); 
 
\t \t \t \t for(i=0;i<retval; i++) 
 
\t \t \t \t { 
 
\t \t \t \t printf("%02X ",(char)recvbuf[i]); 
 
\t \t \t \t } 
 
\t \t \t \t printf("\r\n"); 
 
\t \t \t \t /******************************** 
 
\t \t \t \t echo data back to the client 
 
\t \t \t \t ********************************/ 
 
\t \t \t \t retval = send(asd, (char *)recvbuf, retval, 0, &error); 
 
    printf("3"); 
 
\t \t \t \t if(retval == API_ERROR) 
 
\t \t \t \t { 
 
\t \t \t \t \t printf("\r\nTCPserver: Send error %d",error); 
 
\t \t \t \t \t established = 0; 
 
\t \t \t \t \t break; 
 
\t \t \t \t } 
 
      } 
 
      } 
 
      /***************************************************************** 
 
      Check, if there is more data available at the socket 
 
      *****************************************************************/ 
 
      retval = GetWaitingBytes(asd, &error); 
 
     }//while data available 
 
     while((retval!=API_ERROR) && (retval>0)); 
 
    }//while(established) 
 

 

 
    //close socket, given from accept 
 
    printf("\r\nTCPserver: Closing connection"); 
 
    retval = closesocket(asd, &error); 
 
    if(retval==API_ERROR) 
 
    { 
 
     printf("\r\nTCPserver: Socket close failed: %d",error); 
 
    } 
 
    }//while(1) 
 

 
    /************************************ 
 
    Shutdown server, should not happen 
 
    ************************************/ 
 

 
    printf("\r\nTCPserver: Closing listening socket"); 
 
    retval = closesocket(sd, &error); 
 
    if(retval==API_ERROR) 
 
    { 
 
    printf("\r\nTCPserver: Socket close failed %d",error); 
 
    } 
 
    return 0; 
 
} 
 
// End of file

+0

是的,你當然可以做到這一點。 – ThingyWotsit

+0

謝謝你的回覆,你能告訴我更多一點嗎?我真的需要幫助 –

+0

調整你的服務器和客戶端文件。使用'startClient()'和'startServer()'來回放main()。以通常的方式創建一個帶有main()的第三個單元,並且只有main()調用startClient。檢查它仍然可以作爲客戶端運行。編輯main()僅調用startServer。檢查它仍然可以作爲服務器正常工作。編輯main以啓動startClient()和startServer()的單獨線程,然後卡住,例如在控制檯讀取循環中。現在你應該有一個服務器和客戶端在同一個進程中工作:) – ThingyWotsit

回答

0

我不知道你所說的「在同一程序」的意思。您目前有兩個不同的程序(因爲您有兩個int main(void)函數)。您可以使用多線程將客戶端和服務器都集中在一個可執行文件中,但我無法看到這種情況可能會有所幫助。

如果你想要更具體的幫助,我會建議做一個更小的例子,更精確地展示你當前如何使用線程。否則,查找一個簡單的多線程教程可能是明智的,然後添加它,直到它達到您目前看起來在您的程序中的複雜程度。

+0

'但我看不出在這可能是有利的情況' - 同行對等網絡。 – ThingyWotsit

+0

根據我的理解,上述問題中* server *的類型更類似於點對點網絡情況下的洪流跟蹤器。但你是完全正確的,我應該想到這一點。 – juef

+0

謝謝你的回覆,'但是我沒有看到這種情況可能是有利的。''我的項目經理(我的老師)想要它,兩個程序都運行在他說的同一個程序中,但我不知道如何使用這個 –

相關問題