程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 用C說話停止最根本的socket編程

用C說話停止最根本的socket編程

編輯:關於C++

用C說話停止最根本的socket編程。本站提示廣大學習愛好者:(用C說話停止最根本的socket編程)文章只能為提供參考,不一定能成為您想要的結果。以下是用C說話停止最根本的socket編程正文


甚麼是socket
  你常常聽到人們議論著 “socket”,也許你還不曉得它切實其實切寄義。如今讓我告知你:它是應用 尺度Unix 文件描寫符 (file descriptor) 和其它法式通信的方法。甚麼?你或許聽到一些Unix高手(hacker)如許說過:“呀,Unix中的一切就是文件!”誰人家伙或許正在說到一個現實:Unix 法式在履行任何情勢的 I/O 的時刻,法式是在讀或許寫一個文件描寫符。一個文件描寫符只是一個和翻開的文件相干聯的整數。然則(留意前面的話),這個文件能夠是一個收集銜接,FIFO,管道,終端,磁盤上的文件或許甚麼其它的器械。Unix 中一切的器械就是文件!所以,你想和Internet上其余法式通信的時刻,你將要應用到文件描寫符。你必需懂得適才的話。如今你腦海中也許冒出如許的動機:“那末我從哪裡獲得收集通信的文件描寫符呢?”,這個成績不管若何我都要答復:你應用體系挪用 socket(),它前往套接字描寫符 (socket descriptor),然後你再經由過程它來停止send() 和 recv()挪用。“然則...”,你能夠有很年夜的困惑,“假如它是個文件描寫符,那末為什 麼不消普通挪用read()和write()來停止套接字通信?”簡略的謎底是:“你可使用!”。具體的謎底是:“你可以,然則應用send()和recv()讓你更好的掌握數據傳輸。”存在如許一個情形:在我們的世界上,有許多種套接字。有DARPA Internet 地址 (Internet 套接字),當地節點的途徑名 (Unix套接字),CCITT X.25地址 (你可以將X.25 套接字完整疏忽)。或許在你的Unix 機械上還有其它的。我們在這裡只講第一種:Internet 套接字。
Internet 套接字的兩品種型 :
  甚麼意思?有兩品種型的Internet 套接字?是的。不,我在說謊。其實還有許多,然則我可不想嚇著你。我們這裡只講兩種。除這些, 我盤算別的引見的 "Raw Sockets" 也長短常壯大的,很值得查閱。
那末這兩品種型是甚麼呢?一種是"Stream Sockets"(流格局),別的一種是"Datagram Sockets"(數據包格局)。我們今後談到它們的時刻也會用到"SOCK_STREAM" 和 "SOCK_DGRAM"。數據報套接字有時也叫“無銜接套接字”(假如你確切要銜接的時刻可以用connect()。) 流式套接字是靠得住的雙向通信的數據流。假如你向套接字按次序輸入“1,2”,那末它們將按次序“1,2”達到另外一邊。它們是無毛病的傳遞的,有本身的毛病掌握,在此不評論辯論。
    有甚麼在應用流式套接字?你能夠據說過 telnet,不是嗎?它就應用流式套接字。你須要你所輸出的字符按次序達到,不是嗎?異樣,WWW閱讀器應用的 HTTP 協定也應用它們來下載頁面。現實上,當你經由過程端口80 telnet 到一個 WWW 站點,然後輸出 “GET pagename” 的時刻,你也能夠獲得 HTML 的內容。為何流式套接字可以到達高質量的數據傳輸?這是由於它應用了“傳輸掌握協定 (The Transmission Control Protocol)”,也叫 “TCP” (請參考 RFC-793 取得具體材料。)TCP 掌握你的數據按次序達到而且沒有錯
誤。你或許聽到 “TCP” 是由於聽到過 “TCP/IP”。這裡的 IP 是指“Internet 協定”(請參考 RFC-791。) IP 只是處置Internet 路由罷了。
    那末數據報套接字呢?為何它叫無銜接呢?為何它是弗成靠的呢?有如許的一些現實:假如你發送一個數據報,它能夠會達到,它能夠順序倒置了。假如它達到,那末在這個包的外部是無毛病的。數據報也應用 IP 作路由,然則它不應用 TCP。它應用“用戶數據報協定 (User Datagram Protocol)”,也叫 “UDP” (請參考 RFC-768。)
    為何它們是無銜接的呢?重要是由於它其實不象流式套接字那樣保持一個銜接。你只需樹立一個包,結構一個有目的信息的IP 頭,然後收回去。無需銜接。它們平日應用於傳輸包-包信息。簡略的運用法式有:tftp, bootp等等。
    你或許會想:“假設數據喪失了這些法式若何正常任務?”我的同伙,每一個法式在 UDP 上有本身的協定。例如,tftp 協定每收回的一個被接收到包,收到者必需發還一個包來講“我收到了!” (一個“敕令准確應對”也叫“ACK” 包)。假如在必定時光內(例如5秒),發送方沒有收到應對,它將從新發送,直到獲得 ACK。這一ACK進程在完成SOCK_DGRAM 運用法式的時刻異常主要。

簡略的發送和吸收完成

辦事器端吸收代碼:

#include <Winsock2.h>
#pragma comment(lib,"Ws2_32.lib")
#include <stdio.h>
#include <memory.h>

void main()
{
WSAData wsd;
WSAStartup(MAKEWORD(2,0),&wsd);

SOCKET s =NULL;
s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
struct sockaddr_in ch;
memset(&ch,0,sizeof(ch));
ch.sin_family=AF_INET;
ch.sin_addr.s_addr=INADDR_ANY;
ch.sin_port=htons(1041);
int b=bind(s,(struct sockaddr *) &ch,sizeof(ch));
#define QUEUE_SIZE 5
int l=listen(s,QUEUE_SIZE);
printf("正在監聽本機的1041端口!\n");
SOCKET sc=accept(s,0,0);
printf("客戶端曾經銜接到本機的1041端口!\n");
#define BUF_SIZE 4096
int receByt=0;
while(1)
{
char buf[BUF_SIZE];
receByt=recv(sc,buf,BUF_SIZE,0);
buf[receByt]='\0';
if(receByt>0)
{
printf("吸收的新聞是:%s\n",buf);
}
else
{
printf("吸收新聞停止!");
break;
}

}
int ic=closesocket(sc);
int is=closesocket(s);

}

客戶端發送的代碼:

#include <Winsock2.h>
#pragma comment(lib,"Ws2_32.lib")
#include <stdio.h>
#include <memory.h>
#include <string.h>

void main()
{
WSAData wsd;
WSAStartup(MAKEWORD(2,0),&wsd);

SOCKET s =NULL;
s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
struct sockaddr_in ch;
memset(&ch,0,sizeof(ch));
ch.sin_family=AF_INET;
ch.sin_addr.s_addr=inet_addr("127.0.0.1");
ch.sin_port=htons(1041);

int c=connect(s,(struct sockaddr *) &ch,sizeof(ch));
printf("曾經銜接到辦事器的1041端口!如今可以向辦事器發送新聞了!\n");
#define BUF_SIZE 4096
char info[1024],buf[BUF_SIZE];

while(1)
{
gets(info);
if(info[0]=='\0')
break;
strcpy(buf,info);
int nsend=send(s,buf,strlen(buf),0);

}
int ic=closesocket(s);
}

法式代碼經由了優化,而且整合多線程,把吸收和發送放到統一個文件中,應用參數形式挪用發送和吸收模塊。增長了創立SOCKET的創立的時刻s句柄(或對象)斷定前往值能否為INVALID_SOCKET,和socket的bind操作的前往值能否為SOCKET_ERROR,其他socket的操作應當也斷定SOCKET_ERROR,以包管法式的穩固性,這裡只是測試代碼就不去寫這麼多了,剩下的就由你小我施展。

#include <Winsock2.h>
#pragma comment(lib,"Ws2_32.lib")
#include <stdio.h>
#include <memory.h>
#include <string.h>
#include <pthread.h>


void Receive();
void Send();
void creatThread();

SOCKET s =NULL;
pthread_t t[1000];
int threadCount=0;

void main(int argc,char* argv[])
{
  printf("本法式制造人學號:713901040041\n");
  printf("法式解釋:辦事器端和客戶端為統一個法式,請應用分歧的參數運轉.\n");
  printf("吸收法式請應用 r參數;發送法式請應用 s參數。\n");
  //printf("len : %d\n", argc);
  //printf("count %d\n",argc);
  //printf("value: %s\n",argv[1]);
  //printf("%d",argv[1][0]=='r');

  if(argc<=1)
  {
    printf("please input program arguments ...\n");
    exit(0);
  }
  if(argc>1 && argv[1][0]=='r')
  {
    printf("run receive ...\n");
    Receive();
  }
  if(argc>1 && argv[1][0]=='s')
  {
    printf("run send ...\n");
    Send();
  }
}


void* receiveWork(void * args)
{
  SOCKET sc=accept(s,0,0);
  if(sc==INVALID_SOCKET)
  {
    printf("sc Error");
  }
  creatThread();

  printf("----------客戶端曾經銜接到本機的%d線程銜接!\n",threadCount-2);
#define BUF_SIZE 4096
  int receByt=0;
  while(1)
  {
    char buf[BUF_SIZE];
    receByt=recv(sc,buf,BUF_SIZE,0);
    buf[receByt]='\0';
    if(receByt>0)
    {
      printf("線程吸收的新聞是:%s\n",buf);
    }
    else
    {
      printf("客戶端已加入,");
      break;
    }
      
  }
  int ic=closesocket(sc);
  printf("辦事器停止銜接!\n");
  return NULL;
}

void creatThread()
{
  pthread_create(&t[threadCount++],NULL,receiveWork,NULL);
}


void Receive()
{
  WSAData wsd;
  WSAStartup(MAKEWORD(2,0),&wsd);  
  s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
  if(s==INVALID_SOCKET)
  {
    printf("socket created Error");
  }
  struct sockaddr_in ch;
  memset(&ch,0,sizeof(ch));
  ch.sin_family=AF_INET;
  ch.sin_addr.s_addr=INADDR_ANY;
  ch.sin_port=htons(1041);
  int b=bind(s,(struct sockaddr *) &ch,sizeof(ch));
  if(b==SOCKET_ERROR)
  {
    printf("bind 掉敗,失足代碼是:%d\n",WSAGetLastError());
    exit(0);
  }
#define QUEUE_SIZE 5
  int l=listen(s,QUEUE_SIZE);
  printf("正在監聽本機的1041端口!\n");
  
  creatThread();

  for(int i=0;i<1000;i++)
  {
    pthread_join(t[i],NULL);
  }

int is=closesocket(s);
}



void Send()
{
  WSAData wsd;
  WSAStartup(MAKEWORD(2,0),&wsd);

  SOCKET s =NULL;
  s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
  if(s==INVALID_SOCKET)
  {
    printf("socket created Error");
  }
  struct sockaddr_in ch;
  memset(&ch,0,sizeof(ch));
  ch.sin_family=AF_INET;
  ch.sin_addr.s_addr=inet_addr("127.0.0.1");
  ch.sin_port=htons(1041);

  int c=connect(s,(struct sockaddr *) &ch,sizeof(ch));
  printf("曾經銜接到辦事器的1041端口!如今可以向辦事器發送新聞了!\n");
#define BUF_SIZE 4096
  char info[1024],buf[BUF_SIZE];

  while(1)
  {
    gets(info);
    if(info[0]=='\0')
      break;
    strcpy(buf,info);
    int nsend=send(s,buf,strlen(buf),0);
  }
  int ic=closesocket(s);
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved