صفحه 1 از 2 1 2 آخرینآخرین
نمایش نتایج: از شماره 1 تا 15 از مجموع 16

موضوع: طراحی چت سرور

  
  1. #1


    عضو غیر فعال
    تاریخ عضویت
    Apr 2007
    نوشته
    20
    سپاسگزاری شده
    0
    سپاسگزاری کرده
    3

    Icon14 طراحی چت سرور

    سلام به همه اساتید
    (من تازه کارم) و میخوام یه برنامه چت سرور با سی توی لینوکس بنویسم
    از کجا و با چی شروع کنم؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟ ؟؟؟؟؟؟؟؟؟؟؟؟



  2. #2
    نام حقيقي: Alireza HBB

    عضو غیر فعال شناسه تصویری Alux
    تاریخ عضویت
    Jan 2006
    محل سکونت
    Tehran
    نوشته
    1,492
    سپاسگزاری شده
    286
    سپاسگزاری کرده
    399
    لازم به نوشتن نیست خیلی راحت قابل پیاده سازی هست


    vasighi سپاسگزاری کرده است.

  3. #3


    عضو غیر فعال
    تاریخ عضویت
    Apr 2007
    نوشته
    20
    سپاسگزاری شده
    0
    سپاسگزاری کرده
    3

    چه جوری؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟//

    ممنون از پاسختون ولی چه جوری باید پیاده سازی بشه؟
    در ضمن یه کتاب خوبم برا مطالعه روی شبکه های کلاینت سرور معرفی کنید
    قبلا مچکرم........


    ویرایش توسط vasighi : 2007-05-09 در ساعت 03:05 PM

  4. #4
    نام حقيقي: شاهین غرقی

    خواننده شناسه تصویری webgard3
    تاریخ عضویت
    Feb 2006
    محل سکونت
    iran/shiraz
    نوشته
    3,401
    سپاسگزاری شده
    1040
    سپاسگزاری کرده
    147
    میتونید از چت سرور های آماده مثل digi chat استفاده کنید.


    vasighi سپاسگزاری کرده است.

  5. #5


    عضو غیر فعال
    تاریخ عضویت
    Apr 2007
    نوشته
    20
    سپاسگزاری شده
    0
    سپاسگزاری کرده
    3

    لطفا مرجع معرفی کنید

    نه من میخوام خودم بنویسم
    چه کتاب یا مرجعی رو باید بخونم؟؟؟؟؟؟؟؟؟؟؟



  6. #6
    نام حقيقي: شاهین غرقی

    خواننده شناسه تصویری webgard3
    تاریخ عضویت
    Feb 2006
    محل سکونت
    iran/shiraz
    نوشته
    3,401
    سپاسگزاری شده
    1040
    سپاسگزاری کرده
    147
    asp dot net انتشارات microsoft press.



  7. #7
    نام حقيقي: Mobin

    عضو عادی
    تاریخ عضویت
    Feb 2007
    محل سکونت
    Golestan, Gonbad Qabous
    نوشته
    111
    سپاسگزاری شده
    23
    سپاسگزاری کرده
    11
    سلام
    شما اگر C و مفاهیم شبکه رو به خوبی یاد گرفته باشید با یک مقاله ی کوچیک هم میشه نوشتن Chat Server رو یاد گرفت.من دو تا PDF برای برنامه نویسی شبکه تحت ویندوز براتون upload کردم که واقعاً عالی هستند و میتونید از ایـــنجــــا دانلودش کنید.
    شاید بهتر باشه اول یک برنامه کوچیک بنویسید که فقط یک نفر بتونه با telnet یا Net Cat بهش وصل بشه و هر چیزی که تایپ میشه رو نمایش بده.تا اینجا که پیش رفتید بعد میتونید با تابع SELECT تعداد کلاینت های بیشتری رو پشتیبانی کنید و یک برنامه کلاینت ساده هم بنویسید.



  8. #8


    عضو غیر فعال
    تاریخ عضویت
    Apr 2007
    نوشته
    20
    سپاسگزاری شده
    0
    سپاسگزاری کرده
    3

    خطا

    آدرس error می ده



  9. #9
    نام حقيقي: Mobin

    عضو عادی
    تاریخ عضویت
    Feb 2007
    محل سکونت
    Golestan, Gonbad Qabous
    نوشته
    111
    سپاسگزاری شده
    23
    سپاسگزاری کرده
    11
    سلام
    بله،مثل اینکه هاستم مشکل داره،شما فعلاً از ایـــنجـــا دانلودش کن تا یه فکری به حال اونجا بکنم!



  10. #10


    عضو غیر فعال
    تاریخ عضویت
    Apr 2007
    نوشته
    20
    سپاسگزاری شده
    0
    سپاسگزاری کرده
    3

    تشکر

    دستتون درد نکنه



  11. #11


    عضو غیر فعال
    تاریخ عضویت
    Apr 2007
    نوشته
    20
    سپاسگزاری شده
    0
    سپاسگزاری کرده
    3

    rahnamai

    mishe lotfan bishtar rahnamaim konid



  12. #12


    عضو غیر فعال
    تاریخ عضویت
    Apr 2007
    نوشته
    20
    سپاسگزاری شده
    0
    سپاسگزاری کرده
    3
    سلام
    من این کد برنامه رو نوشتم( البته توی لینوکس) و وقتی با تلنت بهش وصل میشم با (هر چند تا کلاینت که میخوام )هر چیزی رو که روی یک کلاینت تایپ میکنم روی تمام کلاینت های دیگه هم نشون داده میشه .حالا میخوام مثل یه برنامه چت واقعی یه کلاینت بتونه طرف چت خودش رو انتخاب کنه نه اینکه multicast باشه.
    و یه چیز دیگه...
    میشه یه جوری نوشت که بدون تلنت کار کنه یعنی یه برنامه کلاینت بنویسم و به جای تلنت به سرور برنامه کلاینت رو اجرا کنم؟

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #define PORT 9034 // port we’re listening on
    int main(void)
    {
    fd_set master; // master file descriptor list
    fd_set read_fds; // temp file descriptor list for select()
    struct sockaddr_in myaddr; // server address
    struct sockaddr_in remoteaddr; // client address
    int fdmax; // maximum file descriptor number
    int listener; // listening socket descriptor
    int newfd; // newly accept()ed socket descriptor
    char buf[256]; // buffer for client data
    int nbytes;
    int yes=1; // for setsockopt() SO_REUSEADDR, below
    int addrlen;
    int i, j;
    FD_ZERO(&master); // clear the master and temp sets
    FD_ZERO(&read_fds);
    // get the listener
    if ((listener = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("socket");
    exit(1);
    }
    // lose the pesky "address already in use" error message
    if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes,
    sizeof(int)) == -1) {
    perror("setsockopt");
    exit(1);
    }
    // bind
    myaddr.sin_family = AF_INET;
    myaddr.sin_addr.s_addr = INADDR_ANY;
    myaddr.sin_port = htons(PORT);
    memset(&(myaddr.sin_zero), ’\0’, 8);
    if (bind(listener, (struct sockaddr *)&myaddr, sizeof(myaddr)) == -1) {
    perror("bind");
    exit(1);
    }
    // listen
    if (listen(listener, 10) == -1) {
    perror("listen");
    exit(1);
    }
    // add the listener to the master set
    FD_SET(listener, &master);
    // keep track of the biggest file descriptor
    fdmax = listener; // so far, it’s this one
    // main loop
    for(; {
    read_fds = master; // copy it
    if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) {
    perror("select");
    exit(1);
    }

    // run through the existing connections looking for data to read
    for(i = 0; i <= fdmax; i++) {
    if (FD_ISSET(i, &read_fds)) { // we got one!!
    if (i == listener) {
    // handle new connections
    addrlen = sizeof(remoteaddr);
    if ((newfd = accept(listener, (struct sockaddr *)&remoteaddr,
    &addrlen)) == -1) {
    perror("accept");
    } else {
    FD_SET(newfd, &master); // add to master set
    if (newfd > fdmax) { // keep track of the maximum
    fdmax = newfd;
    }
    printf("selectserver: new connection from %s on "
    "socket %d\n", inet_ntoa(remoteaddr.sin_addr), newfd);
    }
    } else {
    // handle data from a client
    if ((nbytes = recv(i, buf, sizeof(buf), 0)) <= 0) {
    // got error or connection closed by client
    if (nbytes == 0) {
    // connection closed
    printf("selectserver: socket %d hung up\n", i);
    } else {
    perror("recv");
    }
    close(i);
    FD_CLR(i, &master); // remove from master set
    } else {
    // we got some data from a client
    for(j = 0; j <= fdmax; j++) {
    // send to everyone!
    if (FD_ISSET(j, &master)) {
    // except the listener and ourselves
    if (j != listener && j != i) {
    if (send(j, buf, nbytes, 0) == -1) {
    perror("send");
    }
    }
    }
    }
    }
    }
    }
    }
    }
    return 0;
    }




  13. #13
    نام حقيقي: Mobin

    عضو عادی
    تاریخ عضویت
    Feb 2007
    محل سکونت
    Golestan, Gonbad Qabous
    نوشته
    111
    سپاسگزاری شده
    23
    سپاسگزاری کرده
    11
    سلام
    خوشم اومد
    برای سئوال اول باید بگم برای اینکه بتونی مثلاً چند تا اتاق گفتگو داشته باشی باید یه منطقی برای برنامه تعریف کنی که چطور متوجه حضور یک کاربر در یک گفتگوی خاص بشه.چیزی که به نظر من رسید این هست که به صورت پیش فرض چهار پنج تا room تو برنامه تعریف کنی،بعد زمانی که کاربر مثل IRC با دستور Join اون روم رو انتخاب کرد از این به بعد یک بایت به اول همه ی پیام هایی که ارسال می کنه اضافه بشه که نشانه ی شماره ی اطاق گفتگو هست.زمانی که پیام های این کاربر به سرور میرسه اول بایت اول رو میخونی و بعد پیام رو برای کاربرای خاص اون اتاق گفتگو ارسال میکنی که قبلاً با دستور Join اعلام کردن که قصد ورود به چه اتاق گفتگویی رو دارن.
    در واقع باید بشینی همه ی جوانب رو در نظر بگیری و یه پروتکل تعریف کنی.

    در مورد سئوال دوم هم بله میشه یه برنامه ی جدا و اختصاصی طراحی کرد که من یه نمونش رو که جوونی هام نوشته بودم برات میذارم :
    کد:
    /*client.c--This is a Simple TCP Client.*/
    #include <stdio.h>
    #include <stdlib.h>
    #include <winsock2.h>
    #pragma comment(lib,"Ws2_32.lib")
    #define BUFFSIZE 1024
    main(int argc,char **argv)
    {
    int bytes_sent,len;
    char buff[BUFFSIZE];
    SOCKET connsocket;
    WSADATA wsadata;
    struct sockaddr_in server;
    if(WSAStartup(MAKEWORD(2,0),&wsadata) != 0)
    {
    printf("Windows Socket API Startup Failure.Exiting...\n");
    exit(-1);
    }
    else
    if(LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wVersion) != 0)
    {
    printf("Windows Can not Provide Socket v2.0.Exiting...\n");
    exit(-1);
    }
    connsocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = inet_addr(argv[1]);
    printf("%d",atoi(argv[2]));
    server.sin_port = htons(atoi(argv[2]));
    if(connect(connsocket,(struct sockaddr *) &server,sizeof(struct sockaddr)) == 0)
    printf("Successfully Connected...\n Now You can Send Your Message to The"
    " Server.Type \"$\" sign to close the Connection.\n");
    while(*buff != '$')
    {
    gets(buff);
    len = strlen(buff);
    bytes_sent = send(connsocket,buff,len,0);
    if(bytes_sent == SOCKET_ERROR)
    printf("Can not Send Data.\n");
    else
    printf("%d Byte(s) Sent!\n",bytes_sent);
    }
    closesocket(connsocket);
    WSACleanup();
    }
    شما پروتکلت رو تعریف کن بعد همینجا کامل توضیح بده،من یه هفته / 10 روز کار دارم،بعد میتونیم بشینیم روش کار کنیم.چون آدم بد قولی هستم قولی نمیدم ولی سعی میکنم با هم تمومش کنیم،خودم هم خیلی وقته دلم برای اینجور کارا تنگ شده!


    ویرایش توسط secure_krnl : 2007-07-29 در ساعت 01:18 PM علت: اشتباه تایپی

  14. #14


    عضو غیر فعال
    تاریخ عضویت
    Apr 2007
    نوشته
    20
    سپاسگزاری شده
    0
    سپاسگزاری کرده
    3

    Icon14

    سلام
    من این برنامه رو نوشتم ولی کار نمی کنه یعنیerror:segmentation error میده یعنی یه بار تا حدی کار کردا ولی وقتی سیستمم رو ریست کردم مدام همین پیغام رو میده بدون اینکه حتی وارد برنامه بشه...
    برنامه کلاینت رو هم نوشتم
    و یه چیز دیگه:میشه کامل برام کار تابعselect رو توضیح بدید و اینکه آیا برا اینکه سرور من بخواد چند تا لاینت رو پشتیبانی کنه باید حتما از این تابع استفاده کنم؟

    کد HTML:
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <sys/socket.h>
    #include <sys/wait.h>
    #include <sys/time.h>
    #include <sys/select.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <signal.h>
    #include <netdb.h>
    #define MYPORT 9000
     
    #define BACKLOG 10
    /*********************************************************/
    struct UsersConnections;
    typedef struct UsersConnections UsersConnections;
    typedef UsersConnections *UsersConnectionsPTR;
     
    struct UsersConnections {
    int sockfd;
    char IP[16];
    char *Nick;
    int Room;
    struct UsersConnections *Prev;
    struct UsersConnections *Next;
    };
    UsersConnectionsPTR UsersConnectionsStart;
    /*********************************************************/
    int ListenConnection(int port);
    void UsersConnectionsDelete(UsersConnectionsPTR *sPtr);
    UsersConnections *UsersConnectionsInsert(UsersConnectionsPTR *sPtr,int sFd,char*sIP,char *sNick);
    int CheckSocketRead(int sockfd);
    UsersConnections *UsersConnectionsInsert(UsersConnectionsPTR *sPtr,int sFd,char
    *sIP,char *sNick);
    int ReadClientData(UsersConnectionsPTR *sConnection);
    int CheckClientData();
    int AcceptClient(int sockfd);
    int Quit(UsersConnectionsPTR *sConnection, char *sReason);
    /**********************************************************/
    main() {printf("salam");
    UsersConnectionsPTR Connection;
    Connection = UsersConnectionsStart;
    int sockfd,newfd,clientfd;
    struct sockaddr_in my_addr;
    struct sockaddr_in their_addr;
    int sin_size;
    UsersConnectionsStart = NULL;
    sockfd = ListenConnection(MYPORT);
    if(!(fork())){
    sin_size=sizeof(struct sockaddr_in);
    // Check for new client connections
    while(1){
    if (CheckSocketRead(sockfd) > 0) {
    // Accept the connection and add user to client list
    newfd=AcceptClient(sockfd);
    }
    //if(!fork()){
    // Check for any incomming data from clients
    CheckClientData();
    if(send(Connection->sockfd,"Hello World!\n",14,0)==-1)
    perror("send");
    //close(newfd);
    Quit(&Connection,"Disconnected");
    exit(0);
    while(waitpid(-1,NULL,WNOHANG)>0);
    }
    }
    //close(newfd);
    Quit(&Connection,"Disconnected");
    }
    /*********************************************************/
    int ListenConnection(int port) {
    int sockfd;
    struct sockaddr_in myaddr;
    myaddr.sin_family = AF_INET;
    myaddr.sin_addr.s_addr = INADDR_ANY;
    myaddr.sin_port = htons(port);
    memset(myaddr.sin_zero, 0, sizeof(myaddr.sin_zero));
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("socket");
    exit(1);
    }
    if (bind(sockfd, (struct sockaddr *)&myaddr, sizeof(struct sockaddr)) == -1) {
    perror("bind");
    exit(1);
    }
    // This will listen to the port but we need another function to check this
    if (listen(sockfd,BACKLOG) == -1) {
    perror("listen");
    exit(1);
    }
    return sockfd;
    }
    /*********************************************************/
    int CheckSocketRead(int sockfd) {
    int rc;
    struct timeval tv;
    fd_set read_fd;
    tv.tv_sec=0;
    tv.tv_usec=1;
    FD_ZERO(&read_fd);
    FD_SET(sockfd, &read_fd);
    printf("salam");
    rc = select(sockfd+1,&read_fd,NULL, NULL, &tv);
    if (rc>0) printf("salam");
    FD_ZERO(&read_fd);
    return rc;
    }
    /*********************************************************/
    int AcceptClient(int sockfd) {
    int newfd, sinsize;
    struct sockaddr_in clientaddr;
    UsersConnectionsPTR Connection;
    char nick[20];
    sinsize = sizeof(struct sockaddr_in);
    newfd = accept(sockfd, (struct sockaddr *)&clientaddr, &sinsize);
    printf("%d",newfd);
    if (newfd == -1) {
    // you don't realy want to exit here as it's only 1 client that can't be accepted
    // however you will be required to investigate why accept returned -1
    perror("accept");
    exit(1);
    //continue;
    } else if (newfd) {
    printf("New CLIENT connection from IP %s on socket %d\n",inet_ntoa(clientaddr.sin_addr), newfd);
    //printf("Please enter your NickName:");
    //gets(nick);
    // Enable non-blocking socket for select()
    //fcntl(newfd,F_SETFL,O_NONBLOCK);
    // Add user to connection list
    Connection=UsersConnectionsInsert(&UsersConnectionsStart,newfd,(char *)inet_ntoa(clientaddr.sin_addr),"nick");
    }
     
    }
    /*********************************************************/
    int CheckClientData() {
    int rc, max;
    struct timeval tv;
    UsersConnectionsPTR Connection, Next;
    char output[1024];
    fd_set usersfd;
    tv.tv_sec=0;
    tv.tv_usec=0;
    Connection = UsersConnectionsStart;
    while (Connection != NULL) {
    Next = Connection->Next;
    FD_ZERO(&usersfd);
    FD_SET(Connection->sockfd, &usersfd);
    errno = 0;
    rc = select(Connection->sockfd+1,&usersfd ,NULL, NULL, &tv);
    if (rc > 0) {
    ReadClientData(&Connection);
    } else if (rc == -1) {
    sprintf(output,"%m\n",errno);
    Quit(&Connection, output);
    }
    Connection = Next;
    }
    }
    /*********************************************************/
    int ReadClientData(UsersConnectionsPTR *sConnection) {
    int i, ch, rc;
    char data[1024], output[1024];
    char buffer[1024];
    UsersConnectionsPTR Connection;
    Connection = *sConnection;
    if(send(Connection->sockfd,"Hello World!\n",14,0)==-1)
    perror("send");
    }
    /*********************************************************/
    UsersConnections *UsersConnectionsInsert(UsersConnectionsPTR *sPtr,int sFd,char
    *sIP,char *sNick)
    {
    UsersConnectionsPTR newPtr, previousPtr, currentPtr, nextPtr;
    newPtr = (UsersConnections *) malloc(sizeof(UsersConnections));
    if (newPtr != NULL) {
    newPtr->sockfd=sFd;
    strcpy(newPtr->IP, sIP);
    strcpy(newPtr->Nick,sNick);
    currentPtr = *sPtr;
    nextPtr = currentPtr->Next;
    newPtr->Next = currentPtr;
    newPtr->Prev = NULL;
    if (currentPtr != NULL) {
    currentPtr->Prev = newPtr;
    }
    *sPtr = newPtr;
    return newPtr;
    } else {
    printf("\n\nmalloc error: out of memory...\n\n");
    return NULL;
    }
    }
    /*********************************************************/
    int Quit(UsersConnectionsPTR *sConnection, char *sReason) {
    char buffer[1024];
    UsersConnectionsPTR Connection;
    Connection = *sConnection;
    close(Connection->sockfd);
    UsersConnectionsDelete(&Connection);
    }
    /*********************************************************/
    void UsersConnectionsDelete(UsersConnectionsPTR *sPtr)
    {
    UsersConnectionsPTR previousPtr, nextPtr, currentPtr, tempPtr;
    tempPtr = *sPtr;
    previousPtr = (*sPtr)->Prev;
    nextPtr = (*sPtr)->Next;
    if (previousPtr == NULL) {
    if (nextPtr != NULL) {
    *sPtr = nextPtr;
    (*sPtr)->Prev = NULL;
    } else {
    *sPtr = NULL;
    }
    } else {
    if (nextPtr != NULL) {
    previousPtr->Next = nextPtr;
    nextPtr->Prev = previousPtr;
    } else {
    previousPtr->Next = NULL;
    }
    }
    free(tempPtr);
    }
    /*********************************************************/
    [LEFT]client side[/LEFT]
    کد HTML:
    [left]#include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>
    #include <netdb.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <sys/socket.h>
    #define PORT 9000 /* the port client will be connecting to */
    #define MAXDATASIZE 100 /* max number of bytes we can get at once */
    int main(int argc, char *argv[])
    {
    int sockfd, numbytes;
    char buf[MAXDATASIZE];
    struct hostent *he;
    struct sockaddr_in their_addr; /* connector's address information */
    if (argc != 2) {
    fprintf(stderr,"usage: client hostname\n");
    exit(1);
    }
    if ((he=gethostbyname(argv[1])) == NULL) { /* get the host info */
    herror("gethostbyname");
    exit(1);
    }
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("socket");
    exit(1);
    }
    their_addr.sin_family = AF_INET; /* host byte order */
    their_addr.sin_port = htons(PORT); /* short, network byte order */
    their_addr.sin_addr = *((struct in_addr *)he-h_addr);
    bzero(&(their_addr.sin_zero), 8); /* zero the rest of the struct */
    if (connect(sockfd, (struct sockaddr *)&their_addr, \
    sizeof(struct sockaddr)) == -1) {
    perror("connect");
    exit(1);
    }
    if ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) == -1) {
    perror("recv");
    exit(1);
    }
    buf[numbytes] = '\0';
    printf("Received: %s",buf);
    close(sockfd);
    return 0;
    }
    [/left]




  15. #15


    عضو غیر فعال
    تاریخ عضویت
    Apr 2007
    نوشته
    20
    سپاسگزاری شده
    0
    سپاسگزاری کرده
    3

    Icon14

    سلام

    من دو برنامه کلاینت c.c وسرور chatserver.c را به همراه برنامه ای که از لیست پیوندی استفاده کرده را دارم و می خوام با استفاده از پروتکل خودم تغییراتی روی آنها بدم.
    سمت سرور به این صورته که اول که سرور اجرا میشه ./chatserver) ) می تونه با چند کلاینت ارتباط برقرار کنه و پیامهایی رو که هر کلاینت می فرسته برای همه کلاینت های دیگه هم می فرسته .
    و سمت کلاینت(./c 127.0.0.1 9000) اینطوریه که اولا هر کلاینت تا پیامی نفرسته هیچ پیامی دریافت نمی کنه .یعنی recv() به شرط send() امکان پذیر هست و به محض اینکه اولین پیام را فرستاد تمام پیامهایی را که دیگران فرستاده اند را دریافت می کند این ارتباط همچنان هست تا وقتی که یه پیام bye\n دریافت کنه اونوقت connection بسته میشه و برنامه کلاینت تموم میشه.

    اما پروتکلی که من فکر کردم:

    برنامه کلاینت به این صورته که هنگامی که کاربر میخواد به سرور کانکت بشه اسم خودش رو به عنوان آرگومان ورودی وارد میکنه( ./c 127.0.0.1 9000 myname) وبعد از connect()شدن این آرگومان را( به عنوان فیلد name استراکچر UsersConnections) به سرور میفرسته و سروربعد از accept() کردن آن کاربر, توسط تابع insert() آن را داخل فیلد name به همراه اطلاعات دیگه کاربر کانکت شده(sockfd,ip,.. )به لیست پیوندی اضافه میکنه.(یا داخل آرایه ای از استراکچر UsersConnections )
    کد HTML:
    [//client side
    [msg.payload=argv[3];
    [Send(clientsockfd,msg);

    ("تقریبا" برنامه سرور با استفاده از لیست پیوندی)


    //server side

    کد HTML:
    [left]#include <sys/time.h>
    #include <sys/select.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <signal.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>
    #include <netdb.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <sys/socket.h>
    [right] [/right][/left][right][/right]
    [left]#define PORT 9000
    #define MAXDATASIZE 100
     
    struct UsersConnections;
    typedef struct UsersConnections UsersConnections;
    typedef UsersConnections *UsersConnectionsPTR;
    // List of users connections to server
    struct UsersConnections {
    int sockfd;
    char IP[16];
    char name[100];
    struct UsersConnections *Prev;
    struct UsersConnections *Next;
    } UsersConnectionsPTR UsersConnectionsStart;
    ****************************************************
    int Quit(UsersConnectionsPTR *sConnection, char *sReason) {
    char buffer[1024];
    //UsersPTR From;
    UsersConnectionsPTR Connection;
    Connection = *sConnection;
    //From = (*sConnection)->User;
    // close file descriptor
    close(Connection->sockfd);
    // Delete 
    //UsersDelete(&From);
    // Delete connection 
    UsersConnectionsDelete(&Connection);
    }
    *****************
    void handle_signal(int signum) {
    // This will require you to research more on signal handling
    printf("SIGNAL %d\n", signum);
    if (signum == 11 || signum == 2) exit(0);
    }
    ********************
    /*int CheckSocketWrite(int sockfd) {
    int rc;
    struct timeval tv;
    fd_set write_fd;
    tv.tv_sec=0;
    tv.tv_usec=1;
    FD_ZERO(&write_fd);
    FD_SET(sockfd, &write_fd);
    rc = select(sockfd+1, NULL, &write_fd, NULL, &tv);
    FD_ZERO(&write_fd);
    return rc;
    }*/
    *********************
    UsersConnections *UsersConnectionsInsert(UsersConnectionsPTR *sPtr,int sFd,char *sIP,char *sNick)
     {
    UsersConnectionsPTR newPtr, previousPtr, currentPtr, nextPtr;
    newPtr = (UsersConnections *) malloc(sizeof(UsersConnections));
    if (newPtr != NULL) {
    newPtr->sockfd=sFd;
    strcpy(newPtr->IP, sIP);
    strcpy(newPtr->Nick,sNick);
    currentPtr = *sPtr;
    nextPtr = currentPtr->Next;
    newPtr->Next = currentPtr;
    newPtr->Prev = NULL;
    if (currentPtr != NULL) {
    currentPtr->Prev = newPtr;
    }
    *sPtr = newPtr;
    return newPtr;
    } else {
    printf("\n\nmalloc error: out of memory...\n\n");
    return NULL;
    }
    }
    ***********************
    void UsersConnectionsDelete(UsersConnectionsPTR *sPtr)
    {
    UsersConnectionsPTR previousPtr, nextPtr, currentPtr, tempPtr;
    tempPtr = *sPtr;
    previousPtr = (*sPtr)->Prev;
    nextPtr = (*sPtr)->Next;
    if (previousPtr == NULL) {
    if (nextPtr != NULL) {
    *sPtr = nextPtr;
    (*sPtr)->Prev = NULL;
    } else {
    *sPtr = NULL;
    }
    } else {
    if (nextPtr != NULL) {
    previousPtr->Next = nextPtr;
    nextPtr->Prev = previousPtr;
    } else {
    previousPtr->Next = NULL;
    }
    }
    free(tempPtr);
    }
    ************************
    UsersConnections *Search(UsersConnectionsPTR *sPtr,char *sNick)
     {
      UsersConnectionsPTR currentPtr;
      currentPtr=*sPtr;
      while (currentPtr != NULL) {
       if (strcasecmp(currentPtr->Nick,sNick) == 0) {
         return currentPtr;
         }  
       currentPtr=currentPtr->Next;
      }
      return NULL;
    }
    ************************
    /*List data in our linked list:
     
    void List(UsersConnectionsPTR *sPtr) {
      UsersConnectionsPTR currentPtr;
      printf("\n\nListing users\n\n");
      currentPtr = *sPtr;
      while (currentPtr != NULL) {
        printf("Name: %s\n",currentPtr->name);
        currentPtr = currentPtr->Next;
      }
    }*/
     
    ****************************************************
    int main()
     {
    int clientfd;
    pid_t pid;
    int rc, max;
    struct timeval tv;
    char output[1024];
    fd_set usersfd;
    tv.tv_sec=0;
    tv.tv_usec=0;
    int newfd, sinsize, sockfd;
    struct sockaddr_in clientaddr;
    struct sockaddr_in myaddr;
    UsersConnectionsPTR Connection, Next;
    UsersConnectionsStart = NULL;
     
    signal(SIGSEGV,handle_signal);
    signal(SIGINT,handle_signal);
    signal(SIGUSR1,handle_signal);
    signal(SIGUSR2,handle_signal);
    signal(SIGPIPE,SIG_IGN);
     
    sinsize = sizeof(struct sockaddr_in);
    myaddr.sin_family = AF_INET;
    myaddr.sin_addr.s_addr = INADDR_ANY;
    myaddr.sin_port = htons(PORT);
    memset(myaddr.sin_zero, 0, sizeof(myaddr.sin_zero));
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("socket");
    exit(1);
    }
    if (bind(sockfd, (struct sockaddr *)&myaddr, sizeof(struct sockaddr)) == -1) {
    perror("bind");
    exit(1);
    }
    if (listen(sockfd, 100) == -1) {
    perror("listen");
    exit(1);
    }
    if(!fork())
     {
    while(1)
     {
    int rc;
    struct timeval tv;
    fd_set read_fd;
    tv.tv_sec=0;
    tv.tv_usec=1;
    FD_ZERO(&read_fd);
    FD_SET(sockfd, &read_fd);
    rc = select(sockfd+1, &read_fd, NULL, NULL, &tv);
    FD_ZERO(&read_fd);
    If(rc>0)
    newfd = accept(sockfd,(struct sockaddr *)&clientaddr,&sinsize);
    //sockfd:listen socket
    if (newfd == -1) {
    perror("accept");
    exit(1);
    }
    else if (newfd) {
    printf("New CLIENT connection from IP %s on socket %d\n",
    inet_ntoa(clientaddr.sin_addr), newfd);
    fcntl(newfd,F_SETFL,O_NONBLOCK);
    Connection = UsersConnectionsStart;
    while (Connection != NULL) {
    Next = Connection->Next;
    FD_ZERO(&usersfd);
    FD_SET(Connection->sockfd, &usersfd);
    errno = 0;
    rc = select(Connection->sockfd+1, &usersfd, NULL, NULL, &tv);
    if (rc > 0) {
    recv(Connection->sockfd,msg,MAXDATASIZE,0);
    [right]nick=msg.payload;[/right][/left][right][/right]
    [left]// Add user to connection list 
    Connection=UsersConnectionsInsert(&UsersConnectionsStart,newfd,(char*)inet_ntoa(clientaddr.sin_addr),nick);
     
     
    } else if (rc == -1) {
    sprintf(output,"%m\n",errno);
    Quit(&Connection, output);
    }
    Connection = Next;
    }// while (Connection != NULL) 
    usleep(200);
    }// while(1)
    }//if
    }//main
    ********
    [/left]
    و سپس اسم کاربر تازه وارد را به همه کاربران آنلاین اعلام میکنه .((sendtoall(argv[3] is now connected)

    تو قسمت آخر تابع chatserver میتونیم به جای buff,nick که بالا تعریف شد (اسم کلاینت کانکت شده )را بگذاریم

    کد HTML:
    [left].. .. .. .. .. .. .. .. 
    if((nbytes=recv(i,buf,sizeof(buf),0))<=0)
                    { if(nbytes==0)      
                     { printf("select server:socket %d hang up\n",i);
                      } else{ perror("recv error"); 
                           } close(i);
                     FD_CLR(i,&master);
                  } else {for(j=0;j<=fdmax;j++)
                            { if(FD_ISSET(j,&master))
                               {if(j!=listener&&j!=i) 
                                 { if(send(j,strcat(buf,"is now connected\n",nbytes,0)==-1)
                                     {perror("send error");
     
    .. .. .. …. .. .. .. .. .. .. 
    [/left]
    و همینطور نام کاربران آنلاین رابرای کاربر تازه واردلیست میکندو براش میفرسته (با استفاده از تابع( list(UsersConnectionsPTR *user که روی لیست پیوندی اعمال میشه)(این تابع میتونه اینطوری تغییر کنه که بجای printf از sprintf استفاده کنه و اسم کاربرها رو داخل آرایه nick (که داخل تابع main تعریف شده) قرار بده

    کد HTML:
    [left][right]Char nick[][];[/right][/left][right][/right]
    [left][right] sprintf (nick,"%s",UsersConnections.name)[/right][/left][right][/right]
    و سپس این آرایه را به کلاینت بفرستدو کلاینت تک تک خانه های آرایه را چاپ کند
    [left][right]For(i=0;nick[i]!=NULL;i++)[/right][/left][right][/right]
    [left][right]   Printf("%s is Online…", nick[i]);[/right][/left][right][/right]
    [left][right]*****************************[/right][/left][right][/right]
    حالا کاربر برای شروع گفتگو باید درخواست خود را به یکی از این کاربران آنلاین بفرستد
    پیامی که با دستورات recv() و  send() ردوبدل میشه رو به صورت یه استراکچر به صورت زیر تعریف کنیم:
    [left][right]Struct msg {[/right][/left][right][/right]
    [left][right]  char  Payload[256]; [/right][/left][right][/right]
    [left][right]  int sockfd;[/right][/left][right][/right]
    [left][right]} msg;[/right][/left][right][/right]
    [left][/left]
    که فیلد payload خود پیام و sockfd آدرس گیرنده.
    کلاینت نام طرف گفتگوی خودش رو(داخل فیلد payload استراکچر msg قرار می ده )و به سرور می فرسته و سرور یه سرچ روی لیست پیوندی روی این اسم انجام می ده تا آدرسش رو (UsersConnections.sockfd ) بدست بیاره .این میشه آدرس گیرنده .

    حالا این آدرس گیرنده را داخل فیلد sockfdmsg. قرار میده و به کلاینت می فرسته و کلاینت پیام درخواست گفتگو را به سرور می فرسته( ضمن اینکه فیلد آدرس دارای آدرس گیرنده است )و سرور تو یه حلقه for() کلاینت های(سوکت های accept() شده) رو که برا ی دریافت پیام آماده اند ((select(read_fd) رو چک میکنه بعد تو همین حلقه Recv(selectsockfd,msg) رو انجام میده بعد از دریافت پیام (msg) آن را به آدرس گیرنده که داخل خود پیام هست می فرسته .Send(msg.sockfd, msg,);)

    .این سرچ روی یه لیست پیوندی از استراکچر UsersConnections (که یه متغیر سراسری تعریف شده و هر وقت سرور یه کلاینت جدید رو accept() می کنه اونو به این لیست insert() میکنه)انجام میشه که به صورت زیر تعریف شده:

    کد HTML:
    [left][font=Tahoma][left]struct UsersConnections {[/left][/font][left]
    [font=Tahoma]int sockfd;[/font]
    [font=Tahoma]char IP[16];[/font]
    [font=Tahoma]char name[100];[/font]
    [font=Tahoma]struct UsersConnections *Prev;[/font]
    [font=Tahoma]struct UsersConnections *Next;[/font]
    
    [font=Tahoma]} UsersConnectionsPTR UsersConnectionsStart[/font][/left][font=Tahoma][/font][/left]
    <DIV align=left>

    گفتگو تا وقتی ادامه دارد که یکی از طرفین کاراکتر$ را وارد کند آنگاه دوباره به کاربر اجازه ایجاد گفتگوی جدید با فراخوانی تابع talk() داده می شود.
    و اگر کاربر کلمه quit را وارد کند آنگاه disconnect می شود(close(clientsockfd) در سمت سرور سوکت مربوط به کلاینتی که پیام quit را فرستاده می بندد)

    در واقع کد سمت کلاینت بعد از connect() برای گفتگو باید به صورت زیر باشه :
    ......................
    کد HTML:
     
    //chatserver 
     
     
    [left]#include <stdio.h>
     
     
    برنامه سمت سرور :
    
    
    [left]#include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>[/left]
     
    [left]#define PORT 9000
    int main(void)
    { 
    fd_set master;
    fd_set read_fds;
    struct sockaddr_in myaddr;
    struct sockaddr_in remoteaddr;
    int fdmax;
    int listener;
    int newfd;
    char buf[256];
    int nbytes;
    int yes=1;
    int addrlen;
    int i,j;
    FD_ZERO(&master);
    FD_ZERO(&read_fds);[/left]
     
    [left]if((listener=socket(AF_INET,SOCK_STREAM,0))==-1)
    { perror("socket");
    exit(1);
    }
    if(setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int))==-1)
    { perror("setsockopt");
    exit(1);
    }
    myaddr.sin_family=AF_INET;
    myaddr.sin_addr.s_addr=INADDR_ANY;
    myaddr.sin_port=htons(PORT);[/left]
     
    [left]memset(&(myaddr.sin_zero),'\0',8);[/left]
     
    [left]if(bind(listener,(struct sockaddr *)&myaddr,sizeof(myaddr))==-1)
    { perror("bind error");
    exit(1);
    }
    if(listen(listener,10)==-1)
    { perror("listen error");
    exit(1);
    }
    FD_SET(listener,&master);
    fdmax=listener;[/left]
     
    [left]for(;;)
    {
    read_fds=master;
    if(select(fdmax+1,&read_fds,NULL,NULL,NULL)==-1)
    { perror("select error");
    exit(1); 
    }
    for(i=0;i<=fdmax;i++)
    { if(FD_ISSET(i,&read_fds))
    {if(i==listener)
    {addrlen=sizeof(remoteaddr);
    if((newfd=accept(listener,(struct sockaddr *)&remoteaddr,&addrlen))==-1)
    perror("accept error");
    else{ FD_SET(newfd,&master);
    if(newfd>fdmax) 
    fdmax=newfd;
    printf("select server:new connection from %s on socket %d\n",inet_ntoa(remoteaddr.sin_addr),newfd); 
    }
    } else {if((nbytes=recv(i,buf,sizeof(buf),0))<=0)
    { if(nbytes==0) 
    { printf("select server:socket %d hang up\n",i);
    } else{ perror("recv error"); 
    } close(i);
    FD_CLR(i,&master);
    } else {for(j=0;j<=fdmax;j++)
    { if(FD_ISSET(j,&master))
    {if(j!=listener&&j!=i) 
    { if(send(j,buf,nbytes,0)==-1)
    {perror("send error");
    }
    }
    }
    }
    }
    }
    }
    }
    }[/left]
     
    } 
    [/left]
    برنامه سمت کلاینت(c.c )

    کد HTML:
     
    [left]/*client*/ 
     
    
    
    [left]#include <stdio.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h> 
     
    void error(char *msg)
    {
        perror(msg);
        exit(0);
    }
     
    int main(int argc, char *argv[])
    {
        int sockfd, portno, n;
        struct sockaddr_in serv_addr;
        struct hostent *server;
     
        char buffer[256];
        if (argc < 3) {
           fprintf(stderr,"usage %s hostname port\n", argv[0]);
           exit(0);
        }
        portno = atoi(argv[2]);
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd < 0) 
            error("ERROR opening socket");
        server = gethostbyname(argv[1]);
        if (server == NULL) {
            fprintf(stderr,"ERROR, no such host\n");
            exit(0);
        }
        bzero((char *) &serv_addr, sizeof(serv_addr));
        serv_addr.sin_family = AF_INET;
        bcopy((char *)server->h_addr, 
             (char *)&serv_addr.sin_addr.s_addr,
             server->h_length);
        serv_addr.sin_port = htons(portno);
        if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr)) < 0) 
            error("ERROR connecting");
        
        //start of chat
        bzero(buffer,256);
         while(strcasecmp(buffer,"bye")!=0)   {
        bzero(buffer,256);
        printf("Please enter the message: ");
        fgets(buffer,255,stdin);
        n = write(sockfd,buffer,strlen(buffer));
        if (n < 0) 
             error("ERROR writing to socket");
        bzero(buffer,256);
        n = read(sockfd,buffer,255);
        if (n < 0) 
             error("ERROR reading from socket");
        printf("Here is the message: %s\n",buffer);
         
    }//while
    }
    
    [/left][/left]






صفحه 1 از 2 1 2 آخرینآخرین

کلمات کلیدی در جستجوها:

socket fcntl select write chatserver

من میخوام چت کنم

کجا چت کنم؟

سرور چت irc

acceptکردن دو کلاینت

میخوام چت کنم

برنامه سوکت سمت کلاینت و سرور برای لینوکس

کدبرنامه سوکت برای کلاینت وسرور

میخوام با یکی چت کنم

نوشتن chat

تلنت کار نمی کنه

سرور irc

برچسب برای این موضوع

مجوز های ارسال و ویرایش

  • شما نمی توانید موضوع جدید ارسال کنید
  • شما نمی توانید به پست ها پاسخ دهید
  • شما نمی توانید فایل پیوست ضمیمه کنید
  • شما نمی توانید پست های خود را ویرایش کنید
  •