作者 主題: TCP通訊協定的server程式及client程式  (閱讀 13475 次)

0 會員 與 1 訪客 正在閱讀本文。

shihyu

  • 活潑的大學生
  • ***
  • 文章數: 223
    • 檢視個人資料
TCP通訊協定的server程式及client程式
« 於: 2007-02-09 03:32 »
動做


server程式會建立socket,繫結socket,等待client端的連線。
client程式會建立socket,與server連線,若連線成功,會將str字串傳給server,str字串的內容為【品號 品名 售價】的格式,如【A001 電視機 20000.00】
server程式若接受client端的連線,會讀取client端傳送過來的字串,並解析字串內容,算出售價的含稅價,再將處理後的字串回傳給client端。
client端收到server回傳的訊息,會將訊息顯示在螢幕上。


代碼: [選擇]


/* server.c */

#include <stdio.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <netdb.h>

#include <string.h>

#include <stdlib.h>

int port = 8000;

int main(void)

{

  struct sockaddr_in    sin;

  struct sockaddr_in    pin;

  int           mysock;

  int           tempsock;

  int           addrsize;

  char  str[100],str1[20],str2[20],str3[20];

  char  buf[100];

  int           i, len1, len2;

  float c;

  /* 建立socket */

  mysock = socket(AF_INET, SOCK_STREAM, 0);

  if (mysock == -1) {

        perror("call to socket");

        exit(1);

  }

  /* 建立IPv4位址 */

  bzero(&sin, sizeof(sin));

  sin.sin_family = AF_INET;

  sin.sin_addr.s_addr = htonl(INADDR_ANY);

  sin.sin_port = htons(port);

  /* ?結socket */

  if (bind(mysock, (struct sockaddr *)&sin, sizeof(sin)) == -1) {

        perror("call to bind");

        exit(1);

  }

  /* 傾聽 client端 */

  if (listen(mysock, 20) == -1) {

        perror("call to listen");

        exit(1);

  }

  printf("Accepting connections ...\n");

  while(1) {

        /* 接受client端連結 */

        tempsock = accept(mysock, (struct sockaddr *)&pin, &addrsize);

        if (tempsock == -1){

                perror("call to accept");

                exit(1);

        }

 

        /* 接收client端傳來的訊息 */

        len1=recv(tempsock, str, 100, 0);

        printf("\n收到字元數: %d\n",len1);

        str[len1]=0;

        printf("received from client: %s\n", str);

        /* 分析處理client端傳來的訊息 */

        if (len1 > 0) {

                strcpy(str1,strtok(str," "));

                printf("第 1 個字串為: %s\n",str1);            

                strcpy(str2,strtok(NULL," "));

                printf("第 2 個字串為: %s\n",str2);            

                strcpy(str3,strtok(NULL," "));

                printf("第 3 個字串為: %s\n",str3);

                c=atof(str3)*1.05;

                sprintf(buf,"品號為 %s\n品名為 %s\n含稅價為: %.2f\n",str1, str2, c);            

        }

        /* 將處理過的訊息傳回給client端 */

        len2 = strlen(buf);

        if (send(tempsock, buf, len2, 0) == -1) {

                perror("call to send");

                exit(1);

        }

        /* 關閉與client端的連線 */

        close(tempsock);

  }

  return 0;

}









===============================================





代碼: [選擇]

/* client.c */

#include <stdio.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <netdb.h>

int port = 8000;

int main(int argc, char *argv[])

{

  struct sockaddr_in    pin;

  int   mysock;

  char  buf[8192];

  char  *str="A001 電視機 20000.00 ";

  if (argc < 2) {

        printf("使用方法: client 字串\n");

        printf("使用預設字串\n");

  } else {

        str=argv[1];

  }

  /* 建立server IPv4位址 */

  bzero(&pin, sizeof(pin));

  pin.sin_family = AF_INET;

  pin.sin_addr.s_addr = inet_addr("192.168.1.20");

  pin.sin_port = htons(port);

  /* 建立socket */

  mysock = socket(AF_INET, SOCK_STREAM, 0);

  if (mysock == -1) {

        perror("call to socket");

        exit(1);

  }

  /* 連結server */

  if (connect(mysock, (void *)&pin, sizeof(pin)) == -1) {

        perror("call to connect");

        exit(1);

  }

  /* 將str字串傳給 server */

  printf("Sending message %s to server ...\n", str);

  if (send(mysock, str, strlen(str), 0) == -1) {

        perror("Error in send\n");

        exit(1);

  }

  /* 接收 server 回傳的訊息 */

  if (recv(mysock, buf, 8192, 0) == -1) {

        perror("Error in receiving\n");

        exit(1);

  }

  printf("\nResponse from server: \n\n%s\n", buf);

  /* 關閉與server的連線 */

  close(mysock);

  return 0;

}






執行結果如下

首先執行server程式,它會等待client端的連線。

[root@mylinux ex16]# gcc -o server server.c

[root@mylinux ex16]# gcc -o client client.c

[root@mylinux ex16]# ./server

Accepting connections ...

                                                                               

接著在另一個終端機視窗中執行client程式,它會使用預設字串,將str字串傳送給server端,並會接收server回傳的訊息。

[root@mylinux ex16]# ./client

使用方法: client 字串

使用預設字串

Sending message A001 電視機 20000.00  to server ...

                                                                               

Response from server:

                                                                               

品號為 A001

品名為 電視機

含稅價為: 21000.00

                                                                               

而在server端則會顯示解析client端傳來的字串。

[root@mylinux ex16]# ./server

Accepting connections ...

收到字元數: 21

received from client: A001 電視機 20000.00

第 1 個字串為: A001

第 2 個字串為: 電視機

第 3 個字串為: 20000.00                                                                                

另一方面,以可以在client端輸入欲傳至server端的字串。

[root@mylinux ex16]# ./client "A002 音響 15000.00"

Sending message A002 音響 15000.00 to server ...

 

Response from server:

 

品號為 A002

品名為 音響

含稅價為: 15750.00




先編譯兩個檔案我再分別開兩個終端機執行 ./server  & ./client

先執行
[root@mylinux ex16]# ./server
Accepting connections ...

再開另一個終端機
[root@mylinux ex16]# ./client



我的問題如下

不知道為什麼執行 ./client只出現下面兩行
使用方法: client 字串
使用預設字串


下面的字樣都沒出現

Sending message A001 電視機 20000.00  to server ...
Response from server:                      

品號為 A001
品名為 電視機
含稅價為: 21000.00


而server 那端也沒接收到訊息一直停留在
Accepting connections ...
想請問一下這是什麼原因???跟192.168.1.20 位址有關係嗎???或是port 8000??

謝謝

Judge

  • 可愛的小學生
  • *
  • 文章數: 8
    • 檢視個人資料
TCP通訊協定的server程式及client程式
« 回覆 #1 於: 2007-02-13 14:16 »
查一下 IP 192.168.1.20 是否為你的本機 IP,
我在 Redhat 9 下可以正常 work.

可否把你的系統列出來呢?
或是防火牆是否有擋住呢?

drco

  • 可愛的小學生
  • *
  • 文章數: 1
    • 檢視個人資料
回覆: TCP通訊協定的server程式及client程式
« 回覆 #2 於: 2010-01-07 16:34 »
此範例在accept(mysock, (struct sockaddr *)&pin, &addrsize);
前加入 addrsize = sizeof(pin);
或將 int addrsize; 宣告成 socklen_t addrsize

banny110110

  • 可愛的小學生
  • *
  • 文章數: 3
    • 檢視個人資料
回覆: TCP通訊協定的server程式及client程式
« 回覆 #3 於: 2010-01-07 16:56 »
將server.c的htonl(INADDR_ANY);直接改成inet_addr("192.168.1.20");試試看
前提是必須確定192.168.1.20是你server IP
我之前寫這個範例程式也有遇過這個問題 我的做法是這樣改
至於這問題的原因我也不知道