❶ linux socket 服務端 客戶端 怎麼開啟在一個機器上運行 接收通訊完全的新手啊!!!什麼都不會的說。
你先編譯你的服務端程序,然後執行。。。這時相當於你的伺服器就啟動了回。
然後編譯你的答客戶端程序,執行時後面跟上任意參數。。。你就會看到結果的。。。
這應該是socket里的第一個簡單例子。。。看書把socket的一些相關api弄懂。。。~!
❷ Linux socket 底層實現是什麼
Linux支持BSD的套接字和全部的TCP/IP協議,是通過網路協議將其視為一組相連的軟體層來實現的,BSD套接字(BSD Socket)由通用的套接字管理軟體支持,該...
❸ linux socket和sock結構體的區別
//**************************************************************************
/* 1、每一個打開的文件、socket等等都用一個file數據結構代表,這樣文件和socket就通過inode->u(union)中的各個成員來區別:
struct inode {
.....................
union {
struct ext2_inode_info ext2_i;
struct ext3_inode_info ext3_i;
struct socket socket_i;
.....................
} u; };
2、每個socket數據結構都有一個sock數據結構成員,sock是對socket的擴充,兩者一一對應,socket->sk指向對應的sock,sock->socket
指向對應的socket;
3、socket和sock是同一事物的兩個側面,為什麼不把兩個數據結構合並成一個呢?這是因為socket是inode結構中的一部分,即把inode結
構內部的一個union用作socket結構。由於插口操作的特殊性,這個數據結構中需要有大量的結構成分,如果把這些成分全部放到socket
結構中,則inode結構中的這個union就會變得很大,從而inode結構也會變得很大,而對於其他文件系統這個union是不需要這么大的,
所以會造成巨大浪費,系統中使用inode結構的數量要遠遠超過使用socket的數量,故解決的辦法就是把插口分成兩部分,把與文件系
統關系密切的放在socket結構中,把與通信關系密切的放在另一個單獨結構sock中;
*/
struct socket
{
socket_state state; // 該state用來表明該socket的當前狀態
typedef enum {
SS_FREE = 0, /* not allocated */
SS_UNCONNECTED, /* unconnected to any socket */
SS_CONNECTING, /* in process of connecting */
SS_CONNECTED, /* connected to socket */
SS_DISCONNECTING /* in process of disconnecting */
} socket_state;
unsigned long flags; //該成員可能的值如下,該標志用來設置socket是否正在忙碌
#define SOCK_ASYNC_NOSPACE 0
#define SOCK_ASYNC_WAITDATA 1
#define SOCK_NOSPACE 2
struct proto_ops *ops; //依據協議邦定到該socket上的特定的協議族的操作函數指針,例如IPv4 TCP就是inet_stream_ops
struct inode *inode; //表明該socket所屬的inode
struct fasync_struct *fasync_list; //非同步喚醒隊列
struct file *file; //file回指指針
struct sock *sk; //sock指針
wait_queue_head_t wait; //sock的等待隊列,在TCP需要等待時就sleep在這個隊列上
short type; //表示該socket在特定協議族下的類型例如SOCK_STREAM,
unsigned char passcred; //在TCP分析中無須考慮
};
❹ linux中socket是如何調用驅動程序
在 Linux 中包括內嵌的協議 TCP、UDP,當然還有 IP。然後是另外一個協議無關層,提供回了與各個設答備驅動程序通信的通用介面,最下面是設備驅動程序本身。
Linux 中的 socket 結構是 struct sock,這個結構是在 linux/include/net/sock.h 中定義的。這個巨大的結構中包含了特定 socket 所需要的所有狀態信息,其中包括 socket 所使用的特定協議和在 socket 上可以執行的一些操作。
網路子系統可以通過一個定義了自己功能的特殊結構來了解可用協議。每個協議都維護了一個名為 proto 的結構(可以在 linux/include/net/sock.h 中找到)。這個結構定義了可以在從 socket 層到傳輸層中執行特定的 socket 操作(例如,如何創建一個 socket,如何使用 socket 建立一個連接,如何關閉一個 socket 等等)。
❺ linux下socket編程中close()函數
只要不用抄close或fclose,不管把這個socket_fd值存到哪裡,都可以使用。比如:
int socket_fd = socket(...);
int socket_x = socket_fd;
那麼send(socket_x)和send(socket_fd)結果完全一致
❻ Linux下socket編程的sockaddr_in結構體中的__SOCKADDR_COMMON (sin_);是什麼意思
__SOCKADDR_COMMON ();是宏定義的意思,括弧裡面是它的參數,這個宏定義表示的是tcp/ip協議的版本是,ipv4還是ipv6的意思,最後的那個unsigned char sin_zero的大小為什麼做減法呢,是為了保證這個結構提到大小和另一個套接字地址的結構體struct sockaddr的大小一致。這么說不知道你能不能不能理解,第一個參數在實際使的時候一般是個常數。
❼ 優秀的國產高性能TCP/UDP/HTTP開源網路通信框架——HP-Socket
HP-Socket是國人開發的一套高性能的TCP/UDP/HTTP網路通信框架,包含了服務端、客戶端以及Agent組件,可用於各種不同應用場景的通信系統,並且提供了C/C++、C#、Delphi、E、Java、Python等編程語言介面。 HP-Socket 對通信層完全封裝,應用程序不必關注通信層的任何細節;HP-Socket 提供基於事件通知模型的 API 介面,能非常簡單高效地整合到新舊應用程序中。
為了讓使用者能方便快速地學習和使用 HP-Socket,迅速掌握框架的設計思 想和使用方法,特此精心製作了大量 Demo 示例(如:PUSH 模型示例、PULL 模型示例、PACK 模型示例、性能測試示例以及其它編程語言示例)。HP-Socket 目前支持 Windows 和 Linux 平台。
以下來自官網提供的文檔:
應用程序可以根據不同的容量要求、通信規模和資源狀況等現實場景調整 HP-Socket 的 各項性能參數(如:工作線程的數量、緩存池的大小、發送模式和接收模式等),優化資源 配置,在滿足應用需求的同時不必過度浪費資源。
提供官方文檔的目錄截圖,由於文檔非常詳細,就不一一介紹了
下面是一張官方提供的demo項目結構,除了C/C++,還提供了C#、Delphi、E,詳細的內容都在github的倉庫中,感興趣的可以去看看。
HP-Socket憑借著通用性、易用性、高性能、伸縮性可以應用到各種場景,而且官方提供了大量的Demo可供學習,以及非常詳細的PDF文檔,除了支持主流的編程語言,還支持E(易語言)。如果你有更好的推薦或者建議歡迎到評論區留言分享!
❽ linux下socket編程,菜鳥求解。。。
你這個東西問題太多啦,老實說,我那過去編都編不過。我改好了,給你指出幾個重大錯誤!
server:
#include<stdio.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include <unistd.h>
#include<fcntl.h>
#include<string.h>
#define IPADDR "127.0.0.1"
#define PORT 21234
const char *logpath = "./log";
int main()
{
struct sockaddr_in servaddr,cliaddr;
int sockfd,clifd,logfd;
socklen_t clilen;
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
//bzero(&servaddr,sizeof(servaddr));
sockfd=socket(AF_INET,SOCK_STREAM,0);
bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
listen(sockfd,8);
printf("aaaaaaaaaaaaaaaa\n");
char buf[500] = {0};
for(;;)
{
clilen = sizeof(cliaddr);
clifd=accept(sockfd,(struct sockaddr *)&cliaddr,&clilen);
printf("%d\n",clifd);
if(clifd < 0)
{
printf("cccccccccccccccccccccc\n");
continue;
}
else
{
printf("dddddddddddddddddddddddd\n");
strcpy(buf,"welcome to 127.0.0.1:21234");
send(clifd,buf,strlen(buf),0);
}
close(clifd);
}
close(sockfd);
return 0;
}
client:
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#define PORT 43212
#define SERVPORT 21234
#define SERVADDR "127.0.0.1"
int main()
{
int servfd,clifd,connre;
struct sockaddr_in servaddr,cliaddr;
clifd=socket(AF_INET,SOCK_STREAM,0);
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(21234);
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
//bzero(&servaddr,sizeof(servaddr));
if((connre=connect(clifd,(struct sockaddr *)&servaddr,sizeof(servaddr)))<0)
{
printf("sorry,connect wrong\n");
exit(1);
}
printf("%d\n",connre);
printf("connect ok,waiting for the server's message back\n");
int length;
char buf[500];
while(1)
{
if((length = recv(clifd,buf,500,0))<0)
{
continue;
}
else
{
printf("get it ,get it\n");
break;
}
}
printf("hi,it's the client,I have recieve message :'hello,welcome' from server");
close(clifd);
return 0;
}
/////////////////////////////////
錯誤1:bzero(&servaddr,sizeof(servaddr)); //剛賦值又清0,why?
錯誤2:servaddr.sin_port = htons(PORT);//你要連的是serverport
其他的錯誤懶得說了,自己看吧.累死我了
❾ Linux編程socket通信疑問
什麼是Socket
Socket介面是TCP/IP網路的API,Socket介面定義了許多函數或常式,程序員可以用它們來開發TCP/IP網路上的應用程序。要學Internet上的TCP/IP網路編程,必須理解Socket介面。
Socket介面設計者......
答案就在這里:linux
socket
通信編程
----------------------Hi,地球人,我是問答機器人小S,上面的內容就是我狂拽酷炫叼炸天的答案,除了贊同,你還有別的選擇嗎?
❿ linux socket是什麼意思
socket介面是TCP/IP網路的API,socket介面定義了許多函數或常式,程序員可以用它們來開發TCP/IP網路上的應用程序。要學Internet上的TCP/IP網路編程,必須理解socket介面。
socket介面設計者最先是將介面放在Unix操作系統裡面的。如果了解Unix系統的輸入和輸出的話,就很容易了解socket了。網路的 socket數據傳輸是一種特殊的I/O,socket也是一種文件描述符。socket也具有一個類似於打開文件的函數調用socket(),該函數返回一個整型的socket描述符,隨後的連接建立、數據傳輸等操作都是通過該socket實現的。常用的socket類型有兩種:流式socket (SOCK_STREAM)和數據報式socket(SOCK_DGRAM)。流式是一種面向連接的socket,針對於面向連接的TCP服務應用;數據報式socket是一種無連接的socket,對應於無連接的UDP服務應用。
socket建立
為了建立socket,程序可以調用socket函數,該函數返回一個類似於文件描述符的句柄。socket函數原型為:
int socket(int domain, int type, int protocol); domain指明所使用的協議族,通常為PF_INET,表示互聯網協議族(TCP/IP協議族);type參數指定socket的類型: SOCK_STREAM 或SOCK_DGRAM,socket介面還定義了原始socket(SOCK_RAW),允許程序使用低層協議;protocol通常賦值 "0"。 socket()調用返回一個整型socket描述符,你可以在後面的調用使用它。
socket描述符是一個指向內部數據結構的指針,它指向描述符表入口。調用socket函數時,socket執行體將建立一個socket,實際上 "建立一個socket"意味著為一個socket數據結構分配存儲空間。socket執行體為你管理描述符表。 兩個網路程序之間的一個網路連接包括五種信息:通信協議、本地協議地址、本地主機埠、遠端主機地址和遠端協議埠。socket數據結構中包含這五種信息。
socket配置
通過socket調用返回一個socket描述符後,在使用socket進行網路傳輸以前,必須配置該socket。面向連接的socket客戶端通過調用connect函數在socket數據結構中保存本地和遠端信息。無連接socket的客戶端和服務端以及面向連接socket的服務端通過調用 bind函數來配置本地信息。
bind函數將socket與本機上的一個埠相關聯,隨後你就可以在該埠監聽服務請求。bind函數原型為:
int bind(int sockfd,struct sockaddr*my_addr, int addrlen); Sockfd是調用socket函數返回的socket描述符,my_addr是一個指向包含有本機IP地址及埠號等信息的sockaddr類型的指針;addrlen常被設置為sizeof(struct sockaddr)。
struct sockaddr結構類型是用來保存socket信息的:
struct sockaddr {
unsigned short sa_family; /*地址族,AF_xxx*/ char sa_data[14]; /*14位元組的協議地址*/ };
sa_family一般為AF_INET,代表Internet(TCP/IP)地址族;sa_data則包含該socket的IP地址和埠號。 另外還有一種結構類型: struct sockaddr_in {
short int sin_family; /*地址族*/
unsigned short int sin_port; /*埠號*/ struct in_addr sin_addr; /*IP地址*/
unsigned char sin_zero[8];/*填0保持與sockaddr同樣大小*/ };
這個結構更方便使用。sin_zero用來將sockaddr_in結構填充到與struct sockaddr同樣的長度,可以用bzero()或memset()函數將其置為零。指向
sockaddr_in 的指針和指向sockaddr的指針可以相互轉換,這意味著如果一個函數所需參數類型是sockaddr時,你可以在函數調用的時候將一個指向 sockaddr_in的指針轉換為指向sockaddr的指針;或者相反。 使用bind函數時,可以用下面的賦值實現自動獲得本機IP地址和隨機獲取一個沒有被佔用的埠號:
my_addr.sin_port=0; /* 系統隨機選擇一個未被使用的埠號*/ my_addr.sin_addr.s_addr=INADDR_ANY; /* 填入本機IP地址*/
通過將my_addr.sin_port置為0,函數會自動為你選擇一個未佔用的埠來使用。同樣,通過將my_addr.sin_addr.s_addr置為INADDR_ANY,系統會自動填入本機IP地址。
注意在使用bind函數是需要將sin_port和sin_addr轉換成為網路位元組優先順序;而sin_addr則不需要轉換。
計算機數據存儲有兩種位元組優先順序:高位位元組優先和低位位元組優先。Internet上數據以高位位元組優先順序在網路上傳輸,所以對於在內部是以低位位元組優先方式存儲數據的機器,在Internet上傳輸數據時就需要進行轉換,否則就會出現數據不一致。
htonl():把32位值從主機位元組序轉換成網路位元組序 htons():把16位值從主機位元組序轉換成網路位元組序 ntohl():把32位值從網路位元組序轉換成主機位元組序 ntohs():把16位值從網路位元組序轉換成主機位元組序
bind()函數在成功被調用時返回0;出現錯誤時返回 "-1"並將errno置為相應的錯誤號。需要注意的是,在調用bind函數時一般不要將埠號置為小於1024的值,因為1到1024是保留埠號,你可以選擇大於1024中的任何一個沒有被佔用的埠號。
連接建立
面向連接的客戶程序使用connect函數來配置socket並與遠端伺服器建立一個TCP連接,其函數原型為:
int connect(int sockfd, struct sockaddr*serv_addr,int addrlen); Sockfd 是socket函數返回的socket描述符;serv_addr是包含遠端主機IP地址和埠號的指針;addrlen是遠端地質結構的長度。 connect函數在出現錯誤時返回-1,並且設置errno為相應的錯誤碼。
進行客戶端程序設計無須調用bind(),因為這種情況下只需知道目的機器的IP地址,而客戶通過哪個埠與伺服器建立連接並不需要關心,socket執行體為你的程序自動選擇一個未被佔用的埠,並通知你的程序數據什麼時候到達埠。
connect函數啟動和遠端主機的直接連接。只有面向連接的客戶程序使用socket時才需要將此socket與遠端主機相連。無連接協議從不建立直接連接。面向連接的伺服器也從不啟動一個連接,它只是被動的在協議埠監聽客戶的請求。
listen函數使socket處於被動的監聽模式,並為該socket建立一個輸入數據隊列,將到達的服務請求保存在此隊列中,直到程序處理它們。 int listen(int sockfd, int backlog);
Sockfd 是socket系統調用返回的socket 描述符;backlog指定在請求隊列中允許的最大請求數,進入的連接請求將在隊列中等待accept()它們(參考下文)。Backlog對隊列中等待服務的請求的數目進行了限制,大多數系統預設值為20。如果一個服務請求到來時,輸入隊列已滿,該socket將拒絕連接請求,客戶將收到一個出錯信息。
當出現錯誤時listen函數返回-1,並置相應的errno錯誤碼。
accept()函數讓伺服器接收客戶的連接請求。在建立好輸入隊列後,伺服器就調用accept函數,然後睡眠並等待客戶的連接請求。 int accept(int sockfd, void*addr, int*addrlen);
sockfd是被監聽的socket描述符,addr通常是一個指向sockaddr_in變數的指針,該變數用來存放提出連接請求服務的主機的信息(某台主機從某個埠發出該請求);addrten通常為一個指向值為sizeof(struct sockaddr_in)的整型指針變數。出現錯誤時accept函數返回-1並置相應的errno值。 首先,當accept函數監視的 socket收到連接請求時,socket執行體將建立一個新的socket,執行體將這個新socket和請求連接進程的地址聯系起來,收到服務請求的初始socket仍可以繼續在以前的 socket上監聽,同時可以在新的socket描述符上進行數據傳輸操作。 數據傳輸
send()和recv()這兩個函數用於面向連接的socket上進行數據傳輸。 int send(int sockfd, const void*msg, int len, int flags);
Sockfd是你想用來傳輸數據的socket描述符;msg是一個指向要發送數據的指針;Len是以位元組為單位的數據的長度;flags一般情況下置為0(關於該參數的用法可參照man手冊)。
send()函數返回實際上發送出的位元組數,可能會少於你希望發送的數據。在程序中應該將send()的返回值與欲發送的位元組數進行比較。當send()返回值與len不匹配時,應該對這種情況進行處理。
int recv(int sockfd,void*buf,int len,unsigned int flags);