网上几乎找不到合适的C语言SOCKET代码,很多都是十几年前的了。老师布置了这个作业自己调试通过了,但是软件只能用VC6++
软件我会传到网盘,和这个代码文件一起。vc6++使用方法可以自行查阅一下。
效果图在最后
先赞后看,养成习惯
服务端:
// socket server.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
#include "winsock2.h" //winsock相关函数头文件
#include "string.h"
#pragma comment(lib,"ws2_32.lib") //winsock链接库文件
//客户端结构体
typedef struct socket
{
SOCKET client;//客户端套接字
char username[16];//客户名
char buf[256];//消息拼接缓存
int flag;//当前客户端标号
}NewSOCKET;
//最大设置为10人连接
NewSOCKET sClient[10];
//当前客户端的标记
int count=0;
//接收消息与转发消息
DWORD WINAPI AnswerThread(LPVOID lparam)
{
NewSOCKET *Client=(NewSOCKET *)lparam;
char revData[128];
int i=0;
char temp[2]=":";
while (true)
{
//接收数据
int ret = recv(Client->client, revData, 128, 0);
if(ret > 0)
{
//将用户名、“:”和消息拼接成一个字符串
strcpy(Client->buf, Client->username);
strcat(Client->buf, temp);
strcat(Client->buf, revData);
//给除自己外的其他客户端发送数据
for(i=0;i<count;i++)
{
if(i!=Client->flag)
send(sClient[i].client,Client->buf, strlen(Client->buf), 0);
}
}
}
closesocket(Client->client);
printf("线程号%d: 我结束了\n",GetCurrentThreadId());
return 0;
}
int main(int argc, char* argv[])
{
//winsock初始化
WORD sockVersion = MAKEWORD(2,2);
WSADATA wsaData;
if(WSAStartup(sockVersion, &wsaData)!=0)
{
return 0;
}
//socket()
SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(slisten == INVALID_SOCKET)
{
printf("socket error !");
return 0;
}
//设置IP和port
sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(18888);
sin.sin_addr.S_un.S_addr = INADDR_ANY;
//bind()
if(bind(slisten, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)
{
printf("bind error !");
}
//listen()
if(listen(slisten, 5) == SOCKET_ERROR)
{
printf("listen error !");
return 0;
}
//accept()
sockaddr_in remoteAddr;
int nAddrlen = sizeof(remoteAddr);
printf("线程号%d: 初始化完成,服务器等待连接...\n",GetCurrentThreadId());
while (true)
{
sClient[count].client = accept(slisten, (SOCKADDR *)&remoteAddr, &nAddrlen);//接受客户端
sClient[count].flag=count;
recv(sClient[count].client, sClient[count].username, sizeof(sClient[count].username), 0); //接收用户名
if(sClient[count].client == INVALID_SOCKET)
{
printf("accept error !");
continue;
}
printf("线程号%d: 接受到一个连接:%s:%d 用户名:%s \r\n", GetCurrentThreadId(), inet_ntoa(remoteAddr.sin_addr), ntohs(remoteAddr.sin_port),sClient[count].username);
DWORD dwThreadId;
HANDLE hThread;
//创建线程处理消息接收与转发
hThread=CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)AnswerThread,&sClient[count],0,&dwThreadId);
if(hThread==NULL)
{
printf("线程号%d: 创建线程出错\n", GetCurrentThreadId());
}
else
{
printf("线程号%d: 已创建线程(线程号%d)处理当前连接,服务器继续等待新连接...\n", GetCurrentThreadId(),dwThreadId);
CloseHandle(hThread);
}
//标记加一
count++;
}
//closesocket()
closesocket(slisten);
//winsock注销
WSACleanup();
return 0;
}
客户端
// socket client.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "winsock2.h" //winsock相关函数头文件
#include <conio.h>
#pragma comment(lib,"ws2_32.lib") //winsock链接库文件
#define RECV_OVER 1
#define RECV_YET 0
char userName[16] = { 0 };
int iStatus = RECV_YET;
//接受数据
unsigned ThreadRecv(void* param)
{
char buf[128] = { 0 };
while (1)
{
int ret = recv(*(SOCKET*)param, buf, sizeof(buf), 0);
if (ret == SOCKET_ERROR)
{
Sleep(500);
continue;
}
if (strlen(buf) != 0)
{
printf("%s\n", buf);
iStatus = RECV_OVER;
}
else
Sleep(100);
}
return 0;
}
//发送数据
unsigned ThreadSend(void* param)
{
char buf[128] = { 0 };
int ret = 0;
while (1)
{
int c = getch();//为了显示美观,加一个无回显的读取字符函数读取回车
if(c == 72 || c == 0 || c == 68)
continue;
printf("%s: ", userName);
gets(buf);
ret = send(*(SOCKET*)param, buf, sizeof(buf), 0);
if (ret == SOCKET_ERROR)
return 1;
}
return 0;
}
//连接服务器
int ConnectServer()
{
//初始化套接字
WORD sockVersion = MAKEWORD(2,2);
WSADATA data;
if(WSAStartup(sockVersion, &data) != 0)
{
return 0;
}
//socket()
SOCKET sclient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sclient == INVALID_SOCKET)
{
printf("invalid socket !");
return 0;
}
//设置服务器地址
sockaddr_in serAddr;
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(18888);
serAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
printf("connecting......\n");
//连接服务器
if (SOCKET_ERROR == connect(sclient, (SOCKADDR*)&serAddr, sizeof(serAddr)))
{
printf("connect failed with error code: %d\n", WSAGetLastError());
closesocket(sclient);
WSACleanup();
return -1;
}
printf("You have been in the room\n");
//获取用户名
printf("Please input your UserName: ");
gets(userName);
send(sclient, userName, sizeof(userName), 0);
printf("\n\n");
DWORD dwThreadId1,dwThreadId2;
HANDLE hThread1,hThread2;
//开启接受线程和发送线程
hThread1=CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)ThreadRecv,&sclient,0,&dwThreadId1);
hThread2=CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)ThreadSend,&sclient,0,&dwThreadId2);
//关闭句柄
CloseHandle(hThread1);
CloseHandle(hThread2);
//循环很久防止主线程退出
for (int k = 0;k < 1000;k++)
Sleep(10000000);
closesocket(sclient);
WSACleanup();
return 0;
}
int main()
{
ConnectServer(); //连接服务器
return 0;
}
代码以及VC6++软件
链接:https://pan.baidu.com/s/1et0w9ZceMpUO8oppZd3odg
提取码:g37s
代码方面有什么不懂可以留言,但我不一定能解答。