1.1 更改网络IP地址
1.1 windows系统更改IP地址
右下角网络→右击打开网络和Internet设置→更改适配器选项→右击VMware Network Adapter VMnet8→属性→双击Internet网络协议4→更改如下

1.2 ubuntu系统更改IP地址
右上角系统设置→network→右下角options→选择IPv4 settings→下拉选择Manual→Add→填写地址Address与Netmask分别为192.168.0.1 与255.255.255.0,如下

点击保存,在Network界面选择重启,即可生效,如下

备注,两系统的IP地址只需保证前三段一致,最后一位不同即可,无需与上述设置必须一致,比如
windows:192.168.2.1 ubuntu:192.168.2.2
2. 程序编写
2.1 windows下程序代码
client端
#include <stdio.h>
#include <Windows.h>
#pragma comment(lib, "ws2_32.lib")
#define Port 5000
#define IP_ADDRESS "192.168.0.1"
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;
}
2.2 ubuntu下程序代码
server端
#include <unistd.h>
#include <stdio.h>
#include <x86_64-linux-gnu/sys/socket.h>
#include <netinet/in.h>
#include <x86_64-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;
}
3. 编译
windows 下使用vc++6.0编译。
ubuntu下使用gcc编译
4. 通信
4.1 通信前的测试
(可跳过,但建议试一试)
从windows端向ubuntu端ping:
打开windows系统 cmd,输入:ping 192.168.0.1

从ubuntu端向windows端ping:
打开ubuntu系统终端 ,输入:ping 192.168.0.2

互相ping成功,说明可以进行通信。若在通信实验中失败,使用ping检查是一个方向。
4.2 通信实验
注意顺序:
打开ubuntu终端,运行第三步编译的可执行程序;再打开vc++6.0,运行client客户端程序。
在客户端会出现如下界面,说明通信成功:

在windows端输字符串,在ubuntu端即可接收,效果如下:


4.3 注意
若在建立通信过程中出现如下错误:

解决方案可尝试如下:
- 程序执行顺序:先server端(本例中为ubuntu端),后client端(本例中为windows端)
- 在网络适配器设置中,关闭windows互联网网络连接,或者拔掉网线,再运行程序。
- 查看虚拟机的网络设置,可尝试将网络连接该改为VMnet8(NAT模式)

本文详细介绍了如何在Windows与Ubuntu16.04系统之间使用socket进行通信,包括更改网络IP地址,分别在两个系统下编写并编译程序,以及通信测试和注意事项。在通信实验中,需确保双方IP地址在同一子网内,且顺序正确,先启动服务器端程序,再启动客户端程序。
458





