用socket實現Linux和Windows之間的通訊
阿新 • • 發佈:2018-10-31
在日常生活中,絕大部分人使用的機器一般是windows系統,但是對於研發人員,開發、編譯等工作往往是建立在linux機器上。事實上,在伺服器方面,Linux、UNIX和WindowsServer佔據了市場的大部分份額;在超級計算機方面,Linux取代Unix成為了第一大作業系統。
通訊是計算機和作業系統的一大任務,通過ftp、ping、ssh等方式,人們可以很方便與伺服器連線。一個龐大的網路上的兩個程式通過一個雙向的通訊連線實現資料的交換,這個連線的一端稱為一個socket。windows系統使用的是windows socket,而linux使用的posix socket。今天結合了網上一些經典例程,寫了一個簡單的socket程式碼,實現Ubuntu(虛擬機器中)和Windows的通訊。
Windows平臺下客戶端的實現程式碼:
#include <stdio.h>
#include <Windows.h>
#pragma comment(lib, "ws2_32.lib")
#define Port 5000
#define IP_ADDRESS "172.30.70.95"
int main(int argc, char* argv[]) // argc是命令列總的引數個數
{
WSADATA s; // 用來儲存呼叫AfxSocketInit全域性函式返回的Windows Sockets初始化資訊
SOCKET ClientSocket;
struct sockaddr_in ClientAddr; // 一個sockaddr_in型的結構體物件
int ret = 0;
char SendBuffer[MAX_PATH]; // Windows的MAX_PATH預設是260
// 初始化Windows Socket
// WSAStartup函式對Winsock服務的初始化
if (WSAStartup(MAKEWORD(2, 2), &s) != 0) // 通過連線兩個給定的無符號引數,首個引數為低位元組
{
printf("Init Windows Socket Failed! Error: %d\n" , GetLastError());
getchar();
return -1;
}
while (1)
{
// 建立一個套介面
// 如果這樣一個套介面用connect()與一個指定埠連線
// 則可用send()和recv()與該埠進行資料報的傳送與接收
// 當會話結束後,呼叫closesocket()
ClientSocket = socket(AF_INET, // 只支援ARPA Internet地址格式
SOCK_STREAM, // 新套介面的型別描述
IPPROTO_TCP); // 套介面所用的協議
if (ClientSocket == INVALID_SOCKET)
{
printf("Create Socket Failed! Error: %d\n", GetLastError());
getchar();
return -1;
}
ClientAddr.sin_family = AF_INET;
ClientAddr.sin_addr.s_addr = inet_addr(IP_ADDRESS); // 定義IP地址
ClientAddr.sin_port = htons(Port); // 將主機的無符號短整形數轉換成網路位元組順序
memset(ClientAddr.sin_zero, 0X00, 8); // 函式通常為新申請的記憶體做初始化工作
// 連線Socket
ret = connect(ClientSocket,
(struct sockaddr*)&ClientAddr,
sizeof(ClientAddr));
if (ret == SOCKET_ERROR)
{
printf("Socket Connect Failed! Error:%d\n", GetLastError());
getchar();
return -1;
}
else
{
printf("Socket Connect Succeed!");
}
printf("Input Data: ");
while (1)
{
scanf("%s", &SendBuffer);
// 傳送資料至伺服器
ret = send(ClientSocket,
SendBuffer,
(int)strlen(SendBuffer), // 返回傳送緩衝區資料長度
0);
if (ret == SOCKET_ERROR)
{
printf("Send Information Failed! Error:%d\n", GetLastError());
getchar();
break;
}
break;
}
// 關閉socket
closesocket(ClientSocket);
if (SendBuffer[0] == 'q') // 設定輸入第一個字元為q時退出
{
printf("Quit!\n");
break;
}
}
WSACleanup();
getchar();
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
我的linux(Ubuntu)端網路資訊:
linux(Ubuntu)平臺下的伺服器程式碼:
#include <unistd.h>
#include <stdio.h>
#include <i386-linux-gnu/sys/socket.h>
#include <netinet/in.h>
#include <i386-linux-gnu/sys/types.h>
#include <stdlib.h>
#include <string.h>
#define SERVER_PORT 5000
#define LENGTH_OF_LISTEN_QUEUE 20
#define BUFFER_SIZE 10
int main() // (int argc, char* argv[])
{
struct sockaddr_in server_addr;
int server_socket;
int opt = 1;
bzero(&server_addr, sizeof(server_addr)); // 置位元組字串前n個位元組為0,包括'\0'
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htons(INADDR_ANY); // 轉小端,INADDR_ANY就是指定地址為0.0.0.0的地址
server_addr.sin_port = htons(SERVER_PORT);
// 建立一個Socket
server_socket = socket(PF_INET, SOCK_STREAM, 0);
if (server_socket < 0)
{
printf("Create Socket Failed!\n");
exit(1);
}
// bind a socket
setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
if(bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)))
{
printf("Server Bind Port: %d Failed!\n", SERVER_PORT);
exit(1);
}
// 監聽Socket
if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE))
{
printf("Server Listen Failed!\n");
exit(1);
}
while(1)
{
struct sockaddr_in client_addr;
int client_socket;
socklen_t length;
char Buffer[BUFFER_SIZE];
// 連線客戶端Socket
length = sizeof(client_addr);
client_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length);
if (client_socket < 0)
{
printf("Server Accept Failed!\n");
break;
}
// 從客戶端接收資料
while(1)
{
bzero(Buffer, BUFFER_SIZE);
length = recv(client_socket, Buffer, BUFFER_SIZE, 0);
if (length < 0)
{
printf("Server Recieve Data Failed!\n");
break;
}
if ('q' == Buffer[0])
{
printf("Quit!\n");
break;
}
printf("%s\n", Buffer);
break;
}
close(client_socket);
}
close(server_socket);
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
在開啟客戶端時,伺服器端要確保已處於監聽狀態,否則連線失敗:
開啟伺服器端程式如下:
資料傳輸成功:
這個小實驗只花了很少的時間除錯,且只能單向傳送資料,功能單一,純粹只是一個小練習,socket程式設計的除錯中,主要關注程式出錯時返回的錯誤值,從中往往能很快找出程式碼的漏洞。
參考連結:http://blog.csdn.net/feixiaoxing/article/details/8567162
在日常生活中,絕大部分人使用的機器一般是windows系統,但是對於研發人員,開發、編譯等工作往往是建立在linux機器上。事實上,在伺服器方面,Linux、UNIX和WindowsServer佔據了市場的大部分份額;在超級計算機方面,Linux取代Unix成為了第一大作業系統。