socket通信之最簡單的socket通信

http://blog.csdn.net/xluren/article/details/8043484#t15

套接字有三種類型

流式套接字(SOCK_STREAM),數據報套接字(SOCK_DGRAM)及原始套接字。

1.流式套接字提供面向連接、可靠的數據傳輸服務,數據按字節流、按順序收發,保證在傳輸過程中無丟失、無冗余。TCP協議支持該套接字。

2.數據報套接字,提供面向無連接的服務,數據收發無序,不能保證數據的準確到達。UDP協議支持該套接字。

3.原始套接字原始套接字主要用于一些協議的開發,可以進行比較底層的操作。它功能強大,但是沒有上面介紹的兩種套接字使用方便,一般的程序也涉及不到原始套接字。

重要的幾個結構體:

1.sockaddr

[cpp]?view plain?copy
  1. struct?sockaddr??
  2. {??
  3. ????????unsigned?short?sa_family;?/*?address族,?AF_xxx?*/??
  4. ????????char?sa_data[14];?/*?14?bytes的協議地址?*/??
  5. };??

sa_family 一般來說,都是“AFINET”。
sa_data 包含了一些遠程電腦的地址、端口和套接字的數目,它里面的數據是雜溶在一切的。

由于在設置上面比較麻煩,所以有了一個更清晰的結構體數據

2.struct sockaddr_in

注:“in” 代表 “Internet”

[cpp]?view plain?copy
  1. struct?sockaddr_in???
  2. {??
  3. ????????short?int?sin_family;?/*?Internet地址族?*/??
  4. ????????unsigned?short?int?sin_port;?/*?端口號?*/??
  5. ????????struct?in_addr?sin_addr;?/*?Internet地址?*/??
  6. ????????unsigned?char?sin_zero[8];?/*?添0(和struct?sockaddr一樣大小)*/??
  7. };??

3.struct in_addr (Internet地址)

struct in_addr
{
?unsigned long s_addr;
};

一些函數:

1.socket

#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain , int type , int protocol);

說明:

domain 需要被設置為“AF_INET”;

type為套接字類型;

protocol為協議一般設置為0

2.bind()

#include <sys/types.h>
#include <sys/socket.h>
int bind (int sockfd , struct sockaddr *my_addr , int addrlen) ;
參數說明:
sockfd 是由socket()函數返回的套接字描述符。
my_addr 是一個指向struct sockaddr 的指針,包含有關你的地址的信息:名稱、端口和IP 地址,可以將struct sockaddr_in結構體強制類型轉換傳入。
addrlen 可以設置為sizeof(struct sockaddr)。

3.connect()

#include <sys/types.h>
#include <sys/socket.h>
int connect (int sockfd, struct sockaddr *serv_addr, int addrlen);
參數說明:

sockfd :套接字文件描述符,由socket()函數返回的。
serv_addr 是一個存儲遠程計算機的IP 地址和端口信息的結構。
addrlen 應該是sizeof(struct sockaddr)。

4.listen()

#include <sys/socket.h>
int listen(int sockfd, int backlog);
參數說明:

sockfd 是一個套接字描述符,由socket()系統調用獲得。
backlog 是未經過處理的連接請求隊列可以容納的最大數目。

5.accept()

#include <sys/socket.h>
int accept(int sockfd, void *addr, int *addrlen);
參數說明:

sockfd 是正在listen() 的一個套接字描述符。
addr 一般是一個指向struct sockaddr_in 結構的指針;里面存儲著遠程連接過來的計算機的信息(比如遠程計算機的IP 地址和端口)。
addrlen 是一個本地的整型數值,在它的地址傳給accept() 前它的值應該是sizeof(struct sockaddr_in);accept()不會在addr 中存儲多余addrlen bytes 大小的數據。如果accept()函數在addr 中存儲的數據量不足addrlen,則accept()函數會改變addrlen 的值來反應這個情況。

注:調用成功后返回一個標識符,被send或recv用來進行數據的接收和發送

6.send()

#include <sys/types.h>
#include <sys/socket.h>
int send(int sockfd, const void *msg, int len, int flags);
參數說明:
sockfd 是代表你與遠程程序連接的套接字描述符。
msg 是一個指針,指向你想發送的信息的地址。
len 是你想發送信息的長度。
flags 發送標記。一般都設為0(你可以查看send 的man pages 來獲得其他的參數值并且明白各個參數所代表的含義,很多時候只要你手不懶,通過linux的man命令可以獲得很多詳細的說明,另外很多書籍或者博客信息也都是man的中文翻譯)。

7.recv()

#include <sys/types.h>
#include <sys/socket.h>
int recv(int sockfd, void *buf, int len, unsigned int flags);
參數說明:
sockfd 是你要讀取數據的套接字描述符。
buf 是一個指針,指向你能存儲數據的內存緩存區域。
len 是緩存區的最大尺寸。
flags 是recv() 函數的一個標志,一般都為0

到此你可以寫出一個簡單的c/s模式的通信來了。

c/s模式是面向連接的demo

server端:

[cpp]?view plain?copy
  1. <span?style="font-size:14px;">#include<stdio.h>??
  2. #include<stdlib.h>??
  3. #include<string.h>??
  4. #include<errno.h>??
  5. #include<sys/types.h>??
  6. #include<sys/socket.h>??
  7. #include<netinet/in.h>??
  8. #define?MAXLINE?4096??
  9. int?main(int?argc,?char**?argv)??
  10. {??????
  11. ????????int????listenfd,?connfd;??????
  12. ????????struct?sockaddr_in?????servaddr;??????
  13. ????????char????buff[4096];??????
  14. ????????int?????n;??????
  15. ????????if(?(listenfd?=?socket(AF_INET,?SOCK_STREAM,?0))?==?-1?)??
  16. ????????{??????
  17. ????????????????printf("create?socket?error:?%s(errno:?%d)\n",strerror(errno),errno);??????
  18. ????????????????exit(0);??????
  19. ????????}??????
  20. ????????memset(&servaddr,?0,?sizeof(servaddr));??????
  21. ????????servaddr.sin_family?=?AF_INET;??????
  22. ????????servaddr.sin_addr.s_addr?=?htonl(INADDR_ANY);??????
  23. ????????servaddr.sin_port?=?htons(6666);??????
  24. ????????if(?bind(listenfd,?(struct?sockaddr*)&servaddr,?sizeof(servaddr))?==?-1)??
  25. ????????{??????
  26. ????????????????printf("bind?socket?error:?%s(errno:?%d)\n",strerror(errno),errno);??????
  27. ????????????????exit(0);??????
  28. ????????}??????
  29. ????????if(?listen(listenfd,?10)?==?-1)??
  30. ????????{??????
  31. ????????????????printf("listen?socket?error:?%s(errno:?%d)\n",strerror(errno),errno);??????
  32. ????????????????exit(0);??????
  33. ????????}????????
  34. ????????printf("======waiting?for?client's?request======\n");??????
  35. ????????while(1)??
  36. ????????{??????
  37. ????????????????if(?(connfd?=?accept(listenfd,?(struct?sockaddr*)NULL,?NULL))?==?-1)??
  38. ????????????????{??????????
  39. ????????????????????????printf("accept?socket?error:?%s(errno:?%d)",strerror(errno),errno);??????????
  40. ????????????????????????continue;??????
  41. ????????????????}??????
  42. ????????????????n?=?recv(connfd,?buff,?MAXLINE,?0);??????
  43. ????????????????buff[n]?=?'\0';??????
  44. ????????????????printf("recv?msg?from?client:?%s\n",?buff);??????
  45. ????????????????close(connfd);??????
  46. ????????}??????
  47. ????????close(listenfd);??
  48. }</span>??

client端:

[cpp]?view plain?copy
  1. <span?style="font-size:14px;">#include<stdio.h>??
  2. #include<stdlib.h>??
  3. #include<string.h>??
  4. #include<errno.h>??
  5. #include<sys/types.h>??
  6. #include<sys/socket.h>??
  7. #include<netinet/in.h>??
  8. #define?MAXLINE?4096??
  9. int?main(int?argc,?char**?argv)??
  10. {??????
  11. ????????int????sockfd,?n;??????
  12. ????????char????recvline[4096],?sendline[4096];??????
  13. ????????struct?sockaddr_in????servaddr;??????
  14. ????????if(?argc?!=?2)??
  15. ????????{??????
  16. ????????????????printf("usage:?./client?<ipaddress>\n");??????
  17. ????????????????exit(0);??????
  18. ????????}??????
  19. ????????if(?(sockfd?=?socket(AF_INET,?SOCK_STREAM,?0))?<?0)??
  20. ????????{?????
  21. ????????????????printf("create?socket?error:?%s(errno:?%d)\n",?strerror(errno),errno);??????
  22. ????????????????exit(0);??????
  23. ????????}??????
  24. ????????memset(&servaddr,?0,?sizeof(servaddr));??????
  25. ????????servaddr.sin_family?=?AF_INET;??????
  26. ????????servaddr.sin_port?=?htons(6666);??????
  27. ????????if(?inet_pton(AF_INET,?argv[1],?&servaddr.sin_addr)?<=?0)??
  28. ????????{??????
  29. ????????????????printf("inet_pton?error?for?%s\n",argv[1]);??????
  30. ????????????????exit(0);??????
  31. ????????}??????
  32. ????????if(?connect(sockfd,?(struct?sockaddr*)&servaddr,?sizeof(servaddr))?<?0)??
  33. ????????{??????
  34. ????????????????printf("connect?error:?%s(errno:?%d)\n",strerror(errno),errno);??????
  35. ????????????????exit(0);??????
  36. ????????}??????
  37. ????????printf("send?msg?to?server:?\n");?????
  38. ????????
  39. ?while(1)
  40. {
  41. ??fgets(sendline,?4096,?stdin);?????
  42. ?if(?send(sockfd,?sendline,?strlen(sendline),?0)?<?0)?????
  43. ?{??????????
  44. ?????????printf("send?msg?error:?%s(errno:?%d)\n",?strerror(errno),?errno);?????
  45. ????????????????exit(0);??????
  46. ????????} ? ??

  47. }
  48. ????????close(sockfd);??????
  49. ????????exit(0);??
  50. }??
  51. </span> ?

  1. ??fgets(sendline,?4096,?stdin);??????
  2. ????????if(?send(sockfd,?sendline,?strlen(sendline),?0)?<?0)??????
  3. ????????{??????
  4. ????????????????printf("send?msg?error:?%s(errno:?%d)\n",?strerror(errno),?errno);??????
  5. ????????????????exit(0);??????
  6. ????????} ? ??

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/383849.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/383849.shtml
英文地址,請注明出處:http://en.pswp.cn/news/383849.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java環境配置

自己安裝的時候按照一般的安裝方法先配置了JDK的環境&#xff0c;能夠成功顯示java版本后我在安裝eclipse的時候一直提示錯誤&#xff1a; Unfortunately the Java version needed to run Eclipse Installer couldn’t be found on your system. You need the following versio…

Linux I/O復用之select函數詳解

http://blog.csdn.net/y396397735/article/details/55004775 select函數的功能和調用順序 使用select函數時統一監視多個文件描述符的&#xff1a; 1、 是否存在套接字接收數據&#xff1f; 2、 無需阻塞傳輸數據的套接字有哪些? 3、 哪些套接字發生了異常&#xff1f; sel…

【Java學習筆記一】類和對象

面向對象程序設計的一個一個重要特點是&#xff1a;封裝性。 這里的封裝性有兩方面含義&#xff1a;一是將有關的數據和操作代碼封裝在一個對象中形成一個基本單位&#xff0c;各個對象之間相互獨立互不干擾&#xff0c;二是將對象中某些部分對外隱蔽&#xff0c;即隱蔽其內部細…

深入研究socket編程(3)——使用select函數編寫客戶端和服務器

http://blog.csdn.net/chenxun_2010/article/details/50488394 首先看原先《UNIX網絡編程——并發服務器&#xff08;TCP&#xff09;》的代碼&#xff0c;服務器代碼serv.c&#xff1a; [cpp] view plaincopy #include<stdio.h> #include<sys/types.h> #inclu…

Java簡單輸入輸出

不同于面向過程中有直接的輸入輸出函數&#xff0c;Java中的輸入輸出只能通過類來實現。 比較常見的一種是使用Scanner類 需要引入java.util包&#xff0c;即在文件開始加上語句import java.util.*;創建Scanner類對象&#xff0c;屬于標準輸入流。 例如Scanner snew Scanner(S…

Ubuntu安裝搭建Clion環境

嗚嗚嗚&#xff0c;太辛苦了&#xff0c;我終于安裝好這個了。 大概過程就是先在官網下載安裝包&#xff0c;然后解壓以后用終端移動到對應文件夾下運行clin.sh 運行完以后會有一些窗口&#xff0c;第一個選擇don’t~~&#xff0c;然后點擊ok 接受&#xff08;你可以不接受…

UNIX網絡編程——select函數的并發限制和 poll 函數應用舉例

http://blog.csdn.net/chenxun_2010/article/details/50489577 一、用select實現的并發服務器&#xff0c;能達到的并發數&#xff0c;受兩方面限制 1、一個進程能打開的最大文件描述符限制。這可以通過調整內核參數。可以通過ulimit -n來調整或者使用setrlimit函數設置&#x…

【Java學習筆記二】繼承和多態

與C不同的是&#xff0c;在Java中&#xff0c;一個類只能直接繼承另一個類&#xff0c;而不允許繼承多個類&#xff0c;這個新類稱為繼承類、派生類或者子類&#xff0c;而被繼承的類稱為基類或者父類。 繼承類能夠繼承基類的群不屬性和行為。 面向對象程序設計的三大特點為&…

使用poll實現的io多路復用服務端和客戶端

http://blog.csdn.net/robertkun/article/details/52269313 參考&#xff1a;http://www.cnblogs.com/Anker/p/3261006.html 使用poll實現的io多路復用服務端和客戶端。 客戶端通過子進程創建多個客戶端連接。 客戶端每隔1秒向服務端發送一個時間戳&#xff0c; 服務端接收到時…

【Java學習筆記三】抽象類與接口

對象的類型轉換分為自動轉換和強制轉換兩種 派生類向基類轉換是自動轉換&#xff0c;因為派生類中包含基類基類向派生類的轉換是強制轉換 強制類型轉換是通過在轉換對象前面使用圓括號運算符來實現&#xff0c;圓括號內為要轉換的目標類型&#xff0c;格式為&#xff1a; (&…

Epoll 的tcp通信代碼(服務器+客戶端)

http://blog.csdn.net/libinbin_1014/article/details/50096187 Epoll 的tcp通信代碼&#xff08;服務器客戶端&#xff09; /* gcc -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS64 -I${ORACLE_HOME}/rdbms/public -I${ORACLE_HOME}/rdbms/demo -L${ORACLE_HOME}/lib -lclntsh …

【Java學習筆記四】Java中的包

包的聲明和引入&#xff1a;在Java語言系統中&#xff0c;Java編譯器為每一個類生成一個字節碼文件&#xff08;.class&#xff09;&#xff0c;為了對類文件進行分層和按用途分類管理&#xff0c;同時也為了解決相同類名的文件沖突的問題&#xff0c;Java提供了包機制來管理類…

Linux系統編程——線程池

http://blog.csdn.net/tennysonsky/article/details/46490099# 線程池基本原理 在傳統服務器結構中&#xff0c;常是有一個總的監聽線程監聽有沒有新的用戶連接服務器&#xff0c;每當有一個新的用戶進入&#xff0c;服務器就開啟一個新的線程用戶處理這 個用戶的數據包。這個線…

【Java學習筆記五】Java異常處理

異常通常分為三類&#xff1a; 程序可控制的異常&#xff1a;一般是可預見的錯誤&#xff0c;不是致命的。例如&#xff1a;除數為0&#xff0c;數組下標越界。程序不可控制的的異常&#xff1a;這種異常往往是致命的&#xff0c;但是系統可以預見的。例如&#xff1a;系統棧溢…

【C++學習筆記一】C++類和對象詳解

類定義是以關鍵字class開頭&#xff0c;后面跟類的名稱。主體是包含在一對花括號中。類定義后必須跟著一個分號或一個聲明列表。 類的對象的公共數據成員可以使用直接成員訪問運算符.來訪問。需要注意的是&#xff0c;私有的成員和受保護的成員不能直接使用成員訪問運算符來訪…

C語言實現的簡單的線程池

http://www.linuxidc.com/Linux/2013-01/77619.htm 有時我們會需要大量線程來處理一些相互獨立的任務&#xff0c;為了避免頻繁的申請釋放線程所帶來的開銷&#xff0c;我們可以使用線程池。下面是一個C語言實現的簡單的線程池。 頭文件&#xff1a; 1: #ifndef THREAD_POOL_H_…

C++獲取當前時間

可以使用windowsAPI直接獲取。 例如&#xff1a; #include<windows.h> #include<cstdio>using namespace std;int main() {SYSTEMTIME now;GetLocalTime(&now);printf("現在是%02d時%02d分%02d秒\n",now.wHour,now.wMinute,now.wSecond);printf(&…

成員函數后面加上const的作用

const表示成員函數不會修改類中的數據成員。 規則&#xff1a; 在類中被const 聲明的函數只能訪問const 函數&#xff0c;而非const 函數可以訪問任意成員函數。在成員函數中不管數據是否具有const 屬性&#xff0c;編譯器檢查的的是是否有修改&#xff08;賦值&#xff0c;自…

簡單Linux C線程池

http://www.cnblogs.com/venow/archive/2012/11/22/2779667.html 大多數的網絡服務器&#xff0c;包括Web服務器都具有一個特點&#xff0c;就是單位時間內必須處理數目巨大的連接請求&#xff0c;但是處理時間卻是比較短的。在傳統的多線程服務器模型中是這樣實現的&#xff1…

C++創建對象:棧和堆的區別

首先我們應該了解棧和堆的差別&#xff1a; 詳細信息&#xff1a;傳送門 棧相當于函數自帶的存儲空間&#xff0c;在windows下一般為2M,在Linux下一般為8M&#xff0c;存取速度稍微快一點。堆是系統的空間&#xff0c;相對較大&#xff0c;一般為2G&#xff0c;效率稍微慢一點…